Evenly splitting / distributing a list of objects using linq and extension methods

by John Nye

16 Jul
2013

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...

Evenly splitting a list

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.

Comments 0 * Be the first to comment!

Leave a message...

18 Apr
2024