Move existing item to the top of a listview - c#

I add items from an array into a ListView like below:
for (int i = 0; i < dataKeyList.Count; i++)
{
CallTabLv.Items.Add(new { Label = " " + keyArray[i], Value = valueArray[i] });
}
If the keyArray[i] contains an item called CustomerName, how can I move it and its value to the top of the list ?
Edit:
Let say:
string[] arr1 = new string[] { "one", "two", "three" };
string[] arr2 = new string[] { "1", "2", "3" };
for (int i = 0; i < arr1.Length; i++)
{
listView.Items.Add(new { C1 = arr1[i], C2 = arr2[i] });
}
Output:
Col Col2
-----------
one 1
two 2
three 3
I want to move "three 3" to the top of the list, so it would be like:
Col Col2
-----------
three 3
two 2
one 1
Any suggestions?

Instead of adding item, You can use [Items.Insert][1] to insert an item in particular position,It can be used To Change position of an existing item in nth index.
ListViewItem item= new ListViewItem("Test");//Define item here;
if(!CallTabLv.Items.Contains(theItem))
{
CallTabLv.Items.Insert(0,item);
}
else
{
n = CallTabLv.Items.IndexOf(item);
CallTabLv.Items.RemoveAt(n);
CallTabLv.Items.Insert(0, item);
}

Related

Splitting String Arrays into Groups

There is a string [] yield that can contain N count data. I have defined 15 count to be an example.
I want to divide these data into 6 groups.However, I cannot load the last remaining items into the array.
Where am I making a mistake?
string[] tags = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};
double tagLength = (int)Math.Floor(tags.Length / (double)6);
for (int i = 0; i <= tagLength-1; i++)
{
string[] groupArrays = new string[6];
Array.Copy(tags, i * 6, groupArrays, 0, 6);
}
The output i see
[0] = {1,2,3,4,5,6}
[1] = {7,8,9,10,11,12}
Should be output
[0] = {1,2,3,4,5,6}
[1] = {7,8,9,10,11,12}
[2] = {13,14,15}
I would suggest changing your code to calculate the number of groups you need to this:
int groups = (count / groupSize);
bool hasPartialGroup = count % groupSize != 0;
if (hasPartialGroup)
{
++groups;
}
The result of the first line will be integer division, so 15 / 6 will result in 2. We then see if there is a remainder using the remainder operator (%): count % groupSize. If its result isn't 0, then there is a remainder, and we have a partial group, so we have to account for that.
So for groups = 15 and groupSize = 6, we'll get count = 3. For groups = 12 and groupSize = 6, we'll get count = 2, etc.
Fixing your code to use this, it might look like:
string[] tags = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};
int count = tags.Length;
const int groupSize = 6;
int groups = (count / groupSize);
bool hasPartialGroup = count % groupSize != 0;
if (hasPartialGroup)
{
++groups;
}
for (int i = 0; i < groups; i++)
{
// you can't copy beyond the end of the array so we have to choose between the remaining ungrouped items and the group size
int currentGroupSize = Math.Min(tags.Length - i*groupSize, groupSize);
// I'm assuming for a partial group you only want this to be as big as the number of items.
// If you want it to always be 6 then change new string[currentGroupSize] to new string[groupSize] and you should be OK.
string[] groupArrays = new string[currentGroupSize];
Array.Copy(tags, i * groupSize, groupArrays, 0, currentGroupSize);
Console.WriteLine(string.Join(",", groupArrays));
}
Try it online // Example with fixed group size
Alternatively, you could create a batching helper method:
private static IEnumerable<T[]> BatchItems<T>(IEnumerable<T> source, int batchSize)
{
var collection = new List<T>(batchSize);
foreach (var item in source)
{
collection.Add(item);
if (collection.Count == batchSize)
{
yield return collection.ToArray();
collection.Clear();
}
}
if (collection.Count > 0)
{
yield return collection.ToArray();
}
}
This will collect batchSize number items together and then return one group at a time. You can read about how this works with yield return here.
Usage:
string[] tags = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"};
List<string[]> batchedTags = BatchItems(tags, 6).ToList();
This will result in 3 string arrays, containing 1,2,3,4,5,6, 7,8,9,10,11,12, and 13,14,15.
You could also make this into an extension method.
Try it online
If you mean why you are not getting groups of 6, the reason for this is that you are flooring the length of tags / 6. So, if the last group has the length of less that 6, it won't get added. Add this to the end:
if (tags.Length%6!=0) { string[] groupArrays = tags[i..tags.Length] } // You can do this manually.
As said before, it's because you use Math.Floor(). Use either Math.Ceiling or remove the -1 from i<= taglength - 1.
Array.Copy will still produce errors when you're tags aren't an exact multiple of 6.
Below code should do the trick and won't produce an error
string[] tags = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15" };
int baselength = 6;
double tagLength = (int)Math.Floor(tags.Length / (double)6);
int length = baselength;
for (int i = 0; i <= tagLength; i++)
{
string[] groupArrays = new string[baselength];
if (i == tagLength)
length = ((i + 1) * length) - tags.Length;
if(length > 0 && length < baselength)
Array.Copy(tags, i * 6, groupArrays, 0, length);
}
Because you use Math.Floor(...). You should use Math.Ceiling(...) instead.
(int)Math.Floor(15d / 6d) // returns 2 >> 2 groups.
(int)Math.Ceiling(15d / 6d) // returns 3 >> 3 groups.
Beware though, you will get an ArgumentOutOfRangeException in Array.Copy, since index 3 * 6 does not exist. You will have to find a way around that.
One possible solution:
string[] tags = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15" };
double tagLength = (int)Math.Ceiling(tags.Length / (double)6);
for (int i = 0; i <= tagLength - 1; i++)
{
int arrLength = (i + 1) * 6 <= tags.Length ? 6 : tags.Length % 6;
string[] groupArrays = new string[arrLength]; // or six if you always want a length of 6
Array.Copy(tags, i * 6, groupArrays, 0, arrLength);
}
Or using Linq:
for (int i = 0; i < (int)Math.Ceiling(tags.Length / 6d); i++)
{
string[] groupArrays = tags.Skip(i * 6).Take(6).ToArray();
}

How to combine values of several lists into one in C#?

I'm trying to merge several values of diffrent lists into one line.
for example:
list A = [1,2,3,4,5,6,7,8,9]
list B = [A,B,C,D]
list C = [!,?,-]
then ill go with a loop through all lists and the output should be:
line = [1,A,!]
line = [2,B,?]
line = [3,C,-]
line = [4,D,NULL]
line = [5,NULL, NULL]
line = [6 ,NULL ,NULL]...
The result will be added into one object
So far I tried to iterate through my lists with foreach loops but after I debugging it's clear that my approach cant work:
foreach (var item in list1){
foreach (var item2 in list2){
foreach (var item3 in list3){
string line = makeStringFrom(item, item2, item3);
}
}
}
But I dont know how to make it work.
You can also use LINQ functions.
var listA = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var listB = new List<string> { "A", "B", "C", "D" };
var listC = new List<string> { "!", "?", "-" };
var result = Enumerable.Range(0, Math.Max(Math.Max(listA.Count, listB.Count), listC.Count))
.Select(i => new
{
a = listA.ElementAtOrDefault(i),
b = listB.ElementAtOrDefault(i),
c = listC.ElementAtOrDefault(i)
}).ToList();
foreach (var item in result)
{
Console.WriteLine("{0} {1} {2}", item.a, item.b, item.c);
}
Result:
1 A !
2 B ?
3 C -
4 D
5
6
7
8
9
The general method would be:
Find the maximum length of all of the lists
Then create a loop to go from 0 to the max length-1
Check if each list contains that index of the item, and if so,
retrieve the value, otherwise return null
Build your line from those values
You can use this:
var A = new List<string>() { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
var B = new List<string>() { "A", "B", "C", "D" };
var C = new List<string>() { "!", "?", "-"};
var lists = new List<List<string>>() { A, B, C };
int count = 0;
foreach ( var list in lists )
count = Math.Max(count, list.Count);
var result = new List<List<string>>();
for ( int index = 0; index < count; index++ )
{
var item = new List<string>();
result.Add(item);
foreach ( var list in lists )
item.Add(index < list.Count ? list[index] : null);
}
foreach ( var list in result )
{
string str = "";
foreach ( var item in list )
str += ( item == null ? "(null)" : item ) + " ";
str.TrimEnd(' ');
Console.WriteLine(str);
}
We create a list of the lists so you can use that for any number of lists.
Next we take the max count of these lists.
Then we parse them as indicated by the algorithm:
We create a new list.
We add this list to the result that is a list of lists.
We add in this new list each of others lists items while taking null is no more items available.
You can use a StringBuilder if you plan to manage several and big lists to optimize memory strings concatenation.
Fiddle Snippet
Output
1 A !
2 B ?
3 C -
4 D (null)
5 (null) (null)
6 (null) (null)
7 (null) (null)
8 (null) (null)
9 (null) (null)

C# How to calculate all 3 letter combinations with a certain value

I have 11 letters and they have values. The first have the same value as their numbering 1 to 10, but the eleventh has a value of 20. The question is how can I print out all 3 letter combinations with a total value of 23. Can you please help me I don’t even know where to start?
Let's first put your letters into a Dictionary<string, int> where Key is the letter, and Value is the value associated with each key.
var values = new Dictionary<string, int>
{
{ "A", 1 },
{ "B", 2 },
{ "C", 3 },
{ "D", 4 },
{ "E", 5 },
{ "F", 6 },
{ "G", 7 },
{ "H", 8 },
{ "I", 9 },
{ "J", 10 },
{ "K", 20 }
};
To get all 3 letter combos whose values add up to 23, first you need to get all 3 letter combos. So let's do that. The following function iterates through the dictionary and gets all 3 letter combos.
private static List<List<KeyValuePair<string, int>>> GetAll3LetterCombos(Dictionary<string, int> values)
{
var comboList = new List<List<KeyValuePair<string, int>>>();
for (int outer = 0; outer < values.Count; outer++)
{
for (int mid = outer + 1; mid < values.Count; mid++)
{
for (int inner = mid + 1; inner < values.Count; inner++)
{
var combo = new List<KeyValuePair<string, int>>
{
values.ElementAt(outer),
values.ElementAt(mid),
values.ElementAt(inner)
};
comboList.Add(combo);
}
}
}
return comboList;
}
Then, using LINQ, we can filter out that result where the sum of values in each KeyValuePair is equal to 23.
var threeLetterCombos = GetAll3LetterCombos(values);
var addsTo23 = threeLetterCombos.Where(x => x.Sum(y => y.Value) == 23).ToList();
The result:
[A 1] [B 2] [K 20]
[D 4] [I 9] [J 10]
[E 5] [H 8] [J 10]
[F 6] [G 7] [J 10]
[F 6] [H 8] [I 9]
One way to do this is a brute-force solution, where you compare every possible combination of three-letter values and store those that equal 23.
First, a simple class to represent a Letter, that has a Text property and a Value property:
public class Letter
{
public int Value { get; set; }
public char Text { get; set; }
public override string ToString()
{
return $"{Text} ({Value})";
}
}
Then, we can populate a list of these from A-K, where each letter has it's corresponding "index + 1" value except the last, which is 20:
var letters = Enumerable.Range(65, 10)
.Select(i => new Letter {Value = i - 64, Text = (char)i })
.ToList();
letters.Add(new Letter {Value = 20, Text = 'K'});
Then we can create a List<List<Letter>> object to hold the combinations that add up to 23:
var combos = new List<List<Letter>>();
And the brute-force solution is to simply use 3 loops to add a List<Letter> of the sum of each number with every combination of two numbers after it:
for (int first = 0; first < letters.Count; first++)
{
for (int second = first + 1; second < letters.Count; second++)
{
for (int third = second + 1; third < letters.Count; third++)
{
combos.Add(new List<Letter>
{letters[first], letters[second], letters[third]});
}
}
}
When this is done, we can filter and display the results of only those whose sum is 23:
// Output the combinations
Console.WriteLine("Here are the combinations that equal 23:\r\n");
foreach (var combo in combos.Where(c => c.Sum(l => l.Value) == 23))
{
Console.WriteLine(string.Join(" +\t", combo) +
$"\t= {combo.Sum(l => l.Value)}");
}
Output

Dynamic number of nested for loops to list unique combinations of objects

I have n number of lists of objects which I need to convert to a list of object arrays each containing a unique combination of objects from the original lists.
Example:
myList[0] = new List<object>(){a, b, c, d};
myList[1] = new List<object>(){"0", "1", "2", "3", "4"};
myList[2] = new List<object>(){0, 1, 2};
myList[3] = new List<object>(){aClass, bClass}
etc.
Needs to become:
newList[0] = new object[]{a, "0", 0, aClass};
newList[1] = new object[]{a, "0", 0, bClass};
newList[2] = new object[]{a, "0", 1, aClass};
newList[3] = new object[]{a, "0", 1, bClass};
newList[4] = new object[]{a, "0", 2, aClass};
newList[5] = new object[]{a, "0", 2, bClass};
newList[6] = new object[]{a, "1", 0, aClass};
newList[7] = new object[]{a, "1", 0, bClass};
newList[8] = new object[]{a, "1", 1, aClass};
newList[9] = new object[]{a, "1", 1, bClass};
newList[10] = new object[]{a, "1", 2, aClass};
newList[11] = new object[]{a, "1", 2, bClass};
etc.
The order of the variables has to be preserved (the list at myList[0] has to be first, etc) because these object arrays are the parameters passed via reflection:
Indicator temp = (Indicator) newIndicator.Invoke(this, newList[i]);
If the number of lists of objects were static, it might look something like the following:
List<object[]> newList = new List<object[]>();
for(int i = 0; i < myList[0].Count; i++)
{
for(int i2 = 0; i2 < myList[1].Count; i2++)
{
for(int i3 = 0; i3 < myList[2].Count; i3++)
{
for(int i4 = 0; i4 < myList[3].Count; i4++)
{
object[] temp = new object[]{myList[0][i], myList[1][i2], myList[2][i3], myList[3][i4]};
newList.Add(temp);
}
}
}
}
My latest attempt was to create a list of indicies which held the current index of each list and incremented it appropriately, but my math doesn't seem to work out as I scale it out.
private List<object[]> ToParametersList(List<List<object>> listOfLists)
{
int counter = 1;
foreach(List<object> list in listOfLists){ counter *= list.Count; }
List<object[]> returnList = new List<object[]>();
List<int> indicies = new List<int>();
int tempSplit = 0;
List<int> splits = new List<int>();
List<int> splitcounters = new List<int>();
for(int i = 0; i < listOfLists.Count; i++)
{
if(i == 0 && listOfLists[0].Count > 2)
{
splits.Add(counter / listOfLists[0].Count);
tempSplit = counter / listOfLists[0].Count;
} else if(i > 0 && listOfLists[i].Count > 2) {
splits.Add(tempSplit / listOfLists[i].Count);
tempSplit /= listOfLists[i].Count;
} else if(listOfLists[i].Count == 2)
{
splits.Add(1);
}
indicies.Add(0);
splitcounters.Add(1);
}
for(int i = 0; i < counter; i++)
{
object[] newObject = new object[listOfLists.Count];
for(int i2 = 0; i2 < listOfLists.Count; i2++)
{
if(i < splits[i2] * splitcounters[i2] && ((indicies[i2] < listOfLists[i2].Count && listOfLists[i2].Count > 2) || indicies[i2] < listOfLists[i2].Count - 1))
{
newObject[i2] = listOfLists[i2][indicies[i2]];
}
else if(i >= splits[i2] * splitcounters[i2] && ((indicies[i2] < listOfLists[i2].Count && listOfLists[i2].Count > 2) || indicies[i2] < listOfLists[i2].Count - 1))
{
indicies[i2]++;
splitcounters[i2]++;
newObject[i2] = listOfLists[i2][indicies[i2]];
}
else
{
indicies[i2] = 0;
splitcounters[i2]++;
newObject[i2] = listOfLists[i2][indicies[i2]];
}
}
returnList.Add(newObject);
}
return returnList;
}
I have also gone through many of the recursion questions on here and am still having trouble understanding how to apply them to this particular situation (I am relatively new to recursion).
Any help would be greatly appreciated!
EDIT: In Cartesian products with n number of list the OP's post is confusing and the answer provided has no explanation of what is happening. The link to Eric Lippert's Blog is a general overview of Cartesian products which did not help me break the barrier that I needed to properly understand this in the context of what I was trying to do.
To be honest i did not read your last attempt. Other ways using Linq is great but if you really want a recursion follow this way.
To create a good recursion you need to look at which part of method varies and which part does not. the method should take parameters that varies for each call. Also you need if-else to end recursion somewhere.
List<object[]> newList = new List<object[]>();
for(int i = 0; i < myList[0].Count; i++)
{
for(int i2 = 0; i2 < myList[1].Count; i2++)
{
for(int i3 = 0; i3 < myList[2].Count; i3++)
{
for(int i4 = 0; i4 < myList[3].Count; i4++)
{
object[] temp = new object[]{myList[0][i], myList[1][i2], myList[2][i3], myList[3][i4]};
newList.Add(temp);
}
}
}
}
We want to use recursion in this method to be able to use it for any lenght of list.To do this you must convert loop into recursion call. but now you have unknown amount of loops.
The solution is to use params keyword. you can send any amount of int to method. this int's holds the variables i1, i2 , i3 , i4 .... just like the above method you have wrote.
The length of this array (params int[]) is exactly number of loops inside the normal method.
private static void Combine(List<List<object>> myList,List<object[]> newList,params int[] loopInd)
{
if (loopInd.Length <= myList.Count) // should not exceed number of loops.
{
int currentCount = myList[loopInd.Length - 1].Count;
while (loopInd[loopInd.Length - 1] < currentCount) // i<myList[0] , i2<myList[1] , i3<myList[2]
{
Combine(myList, newList, loopInd.Concat(new[] {0}).ToArray()); // Go for inner loop
loopInd[loopInd.Length - 1]++; // i++, i2++ , i3++ ...
}
}
else // no more loops.add the object[] into newList
{
int j = 0;
object[] temp = loopInd.Take(loopInd.Length - 1).Select(i => myList[j++][i]).ToArray();
newList.Add(temp);
}
}
The comments above shows the representations in normal method.
Then you can use it in this way.
List<List<object>> myList = new List<List<object>>();
myList.Add(new List<object>() { a, b, c, d });
myList.Add(new List<object>() { "0", "1", "2", "3", "4" });
myList.Add(new List<object>() { 0, 1, 2 });
myList.Add(new List<object>() {aClass, bClass});
List<object[]> newList = new List<object[]>();
Combine(myList, newList, 0);
// The newList is now what you want
Edit :
If you are after performance you can convert this Linq part
int j = 0;
object[] temp = loopInd.Take(loopInd.Length - 1).Select(i => myList[j++][i]).ToArray();
newList.Add(temp);
Into code
int j = 0;
object[] temp = new object[loopInd.Length - 1];
for (int i = 0; i < loopInd.Length - 1; i++,j++)
{
temp[i] = myList[j][loopInd[i]];
}
Here is a solution that accepts a number of lists that is unknown at compile time.
Method CombineArrayOfLists does what you need:
static List<List<object>> CombineArrayOfLists(List<object>[] myList)
{
List<List<object>> result = myList[0].Select(element => new List<object>() { element }).ToList();
for (int i = 1; i < myList.Length; i++)
{
result = (from c1 in result from c2 in myList[i] select new List<object>(c1) {c2}).ToList();
}
return result;
}
Note that you need to define the desired behavior in case any list in your array of lists is empty. To handle that case you may need to add an if statement to skip that list (if that is the appropriate thing to do).
A complete example written in a slightly more verbose form that could be easier to understand:
class Program
{
static void Main(string[] args)
{
List<object>[] myList = new List<object>[4];
AClass aClass = new AClass();
BClass bClass = new BClass();
myList[0] = new List<object>() { "a", "b", "c", "d" };
myList[1] = new List<object>() { "0", "1", "2", "3", "4" };
myList[2] = new List<object>() { 0, 1, 2 };
myList[3] = new List<object>() { aClass, bClass };
List<List<object>> result = CombineArrayOfLists(myList);
PrintList(result);
}
static List<List<object>> CombineArrayOfLists(List<object>[] myList)
{
List<List<object>> result = myList[0].Select(element => new List<object>() { element }).ToList();
for (int i = 1; i < myList.Length; i++)
{
result = CombineCollections(result, myList[i]).ToList();
}
return result;
}
private static IEnumerable<List<object>> CombineCollections(IEnumerable<List<object>> collection1, List<object> collection2)
{
return from c1 in collection1 from c2 in collection2 select new List<object>(c1) { c2 };
}
// A more verbose form of CombineCollections that may be easier to understand:
//private static IEnumerable<List<object>> CombineCollections(IEnumerable<List<object>> collection1, List<object> collection2)
//{
// foreach (List<object> c1 in collection1)
// {
// foreach (object c2 in collection2)
// {
// List<object> l1 = new List<object>(c1) { c2 };
// yield return l1;
// }
// }
//}
private static void PrintList(List<List<object>> collection)
{
collection.ForEach(list =>
{
list.ForEach(element =>
{
Console.Write(element);
Console.Write(" ");
});
Console.WriteLine();
});
}
}
public class AClass
{ }
public class BClass
{ }
You can use LINQ to get Cartesian product of list of objects.
List<object> arr1 = new List<object> { "a", "b", "c" };
List<object> arr2 = new List<object> { 3, 2, 4,5 };
List<object> arr3 = new List<object> { "0", "1", "2", "3", "4" };
var result = from x in arr1
from y in arr2
from z in arr3
select new { x = x, y = y,z=z };
List<object[]> newList = new List<object[]>();
foreach (var line in result)
{
newList.Add(new object[] { line.x, line.y, line.z });
}
foreach (var obj in newList)
{
foreach (var ele in obj)
{
Console.Write(ele.ToString() + " ");
}
Console.WriteLine();
}
Console.ReadKey();
This will provide you with the list of one objects in the way you require.
Here is the running example
http://csharppad.com/gist/45ebe7c9576dab9c00b8

Dividing items into columns

I have a dynamic number of items to divide into a maximum of 4 columns, with the proper html format surrounding then, lets say:
string[] s = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; // from 1 to n itens
To format into this html:
<ul>
<li>
1
2
3
</li>
<li>
4
5
</li>
<li>
6
7
</li>
<li>
8
9
</li>
</ul>
Edit: my website problem:
If you have words as itens, putting the itens this way will organize the words into alphabetically columns (people read this way), not alphabetically rows. Like:
a d g i
b e h j
c f
Instead of:
a b c d
e f g h
i j
Assuming that you want to evenly distribute any remainders, this will do the job:
string[] s = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
// create the 4 buckets with equal distribution
var buckets = Enumerable.Repeat(s.Length / 4, 4).ToArray();
// distribute any remainders evenly starting from the first bucket
var rem = s.Length % 4;
for (var i = 0; i < rem; i++) buckets[i]++;
var idx = 0;
Console.WriteLine("<ul>");
foreach (var bucket in buckets)
{
Console.WriteLine("\t<li>");
foreach (var _ in Enumerable.Range(1, bucket))
{
Console.WriteLine("\t\t{0}", s[idx++]);
}
Console.WriteLine("\t</li>");
}
Console.WriteLine("</ul>");
For the above code, here is what some edge cases return.
{} = 4 empty items in list
{ "1", "2", "3"} = 1, 2, 3 in the first three items, fourth item empty
{ "1", "2", "3", "4", "5"} = 1, 2 in the first item, 3, 4, 5 in the other items
Just loop over the array distributing the array items with a few if statements within it.
int j = 0;
for (int i = 0; i < s.Length; i++)
{
if (j == 0)
// put s[i] in column 1 j = j +1
else if (j == 1)
// put s[i] in column 2 j = j +1
else if (j == 2)
// put s[i] in column 3 j = j +1
if (j == 3)
// put s[i] in column 4 set j = 0
}
Since you want to group by columns instead of rows, just realize that you're ultimately going to have to do SOMETHING with the index. The easiest way to do this is to transform the items into Item/Index pairs and group by those indexes somehow.
s.Select((tr, ti) => new { Index = ti, Item = tr })
.GroupBy(tr => tr.Index % SOME_MAGIC_NUMBER)
If you want to instead group by rows, change the % operator to a division / and you'll be set. This will now take all your items and group them into the however many items you specify (based on either row or column). To transform them, all you have to do is another select:
.Select(tr => "<li>" + string.Join(" ", tr.Select(tstr => tstr.Item.ToString()).ToArray()) + "</li>")
This will get you a list of all your list items in whatever format you want. If you want to include <br /> between the elements of each <li> then just change the first argument of the string.Join call.

Categories

Resources