how do I chunk an enumerable?
>= .Net 6
Built-in Enumerable.Chunk method:
// Giving an enumerable
var e = Enumerable.Range(1, 999);
// Here it is. Enjoy :)
var chunks = e.Chunk(29);
// Sample, iterating over chunks
foreach(var chunk in chunks) // for each chunk
{
foreach(var item in chunk) // for each item in a chunk
{
Console.WriteLine(item);
}
}
If memory consumption isn't a concern, then like this?
static class Ex
{
public static IEnumerable<IEnumerable<TValue>> Chunk<TValue>(
this IEnumerable<TValue> values,
int chunkSize)
{
return values
.Select((v, i) => new {v, groupIndex = i / chunkSize})
.GroupBy(x => x.groupIndex)
.Select(g => g.Select(x => x.v));
}
}
Otherwise you could get creative with the yield
keyword, like so:
static class Ex
{
public static IEnumerable<IEnumerable<TValue>> Chunk<TValue>(
this IEnumerable<TValue> values,
int chunkSize)
{
using(var enumerator = values.GetEnumerator())
{
while(enumerator.MoveNext())
{
yield return GetChunk(enumerator, chunkSize).ToList();
}
}
}
private static IEnumerable<T> GetChunk<T>(
IEnumerator<T> enumerator,
int chunkSize)
{
do
{
yield return enumerator.Current;
} while(--chunkSize > 0 && enumerator.MoveNext());
}
}