Evenly splitting / distributing a list of objects using linq and extension methods
less than a minute read
An interesting (if not lengthy) question caught my eye on Stack Overflow this evening which I had a crack at so I thought I'd share it.
The simplified problem was, given I have X apples and Y baskets, how can I evenly split the apples into each of the baskets. To do this I ended up creating an IEnumerable
extension method that can be applied to the source (apples)
public static class EnumerableExtensions
{
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, int groups)
{
var listedSource = source.ToList();
int extra;
//Work out if number of items goes exactly into the groups
int groupSize = Math.DivRem(listedSource.Count(), groups, out extra);
while (listedSource.Any())
{
int newSize = groupSize;
if (extra > 0)
{
//If any remainder items exist, increase the group size
newSize++;
extra--;
}
yield return listedSource.Take(newSize);
listedSource = listedSource.Skip(newSize).ToList();
}
}
}
The above extension method enabled me to right the following code to split the apples:
int baskets = 4;
var apples = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var result = apples.Split(baskets);
And here's the proof...
I'd be interested if anyone out there has any other approaches to this problem or any comments on the approach I have put together so please get in touch.