I try to take 3 rows at a time from a List of string but its not working as expected. Consider this code...
var listOfStrings = new List<string>
{
"String 1",
"String 2",
"String 3",
"String 4",
"String 5",
"String 6"
};
foreach (var x in listOfStrings.Take(3).ToList())
{
var currRows = x.ToList();
// currRows should have 3 items
foreach (var itm in currRows)
{
}
}
The first run I expect currRows to have 3 items (String 1, 2 and 3), the second time I expect to have these 3 items (String 4, 5 and 6). But when I run this currRows only contains for example "String 1" and this is split up character by character?!
What am I missing here?
But when I run this currRows only contains for example "String 1" and this is split up character by character?!
That's because Enumerable.Take will take the requested amount of items from the IEnumerable<T>. This makes your x variable be of type string, which you later call ToList() on, effectively creating a List<char>, which isn't what you want.
You can use MoreLINQ which has a Batch extension method which does exactly what you want. It returns an IEnumerable<IEnumerable<T>>:
foreach (var batch in listOfStrings.Batch(3))
{
// batch is an IEnumerable<T>, and will have 3 items.
foreach (var item in batch)
{
}
}
Another possibility is to create that extension method yourself. This is taken from this answer:
public static class EnumerableExtensions
{
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> items,
int maxItems)
{
return items.Select((item, inx) => new { item, inx })
.GroupBy(x => x.inx / maxItems)
.Select(g => g.Select(x => x.item));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With