Monday, November 19, 2007

IEnumerable Joy - Batch / Split

I was inspired by my good friend Nick's latest blog entry Return of the Batch Enumerable

Here he demonstrates a neat idea of using extension methods and yield to split an IEnumerable into arbitrary batches.

My version is slightly less efficient, but treats the batches as separate lazy collections - so you can use it on multiple threads etc.

I've also added a Split extension, which I'll describe - but first, the code!

static class InBatchesExtension
{
public static IEnumerable<IEnumerable<T>> InBatches<T>(this IEnumerable<T> source, int batchSize)
{
for (IEnumerable<T> s = source; s.Any(); s = s.Skip(batchSize))
yield return s.Take(batchSize);
}

public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, int items)
{
for (int i = 0; i < items; ++i)
yield return source.Where((x, index) => (index % items) == i);
}
}

The InBatches returns the same output as Nicks:

Batch: 1 2 3
Batch: 4 5 6
Batch: 7

And the Split batches the output across the collections:

Batch: 1 4 7
Batch: 2 5
Batch: 3 6

So this gives you 2 different batch splitting methods for a generic enumerable.

I love this stuff.

1 comment:

Anonymous said...

hm...thanks. too bad your friend's link is not available anymore.