LINQ method to group collection into subgroups with specified number of elements

Does there exist a LINQ method to group a given collection into subgroups with specified number of elements I mean, something like Scala's grouped method. e.g. in Scala, List(89, 67, 34, 11, 34).grouped(2) gives List(List(89, 67), List(34, 11), List(34)).

In case such a method doesn't exist, what would be the LINQ way to do it?

Answers


Yes, you can. But you can argue if it's very pretty...

  Int64[] aValues = new Int64[] { 1, 2, 3, 4, 5, 6 };
  var result = aValues
          .Select( ( x, y ) => new KeyValuePair<Int64, Int32>( x, y ) )
          .GroupBy( x => x.Value / 2 )
          .Select( x => x.Select( y => y.Key ).ToList() ).ToList();

How it works:

Select x and y from the original collection, where x is the actual value and y is the index of it in the given collection. Then group by integer devision of the index and the desired grouping length ( in this example 2 ).

Grouping by integer devision will round up to the lower - so 0 / 2 = 0, 1 / 2 = 0, etc. which will give us the needed grouping category value. This is what we are grouping against here.

For result select only the values grouped in lists and return them as a collection of lists.


Here is a website that seems to have some sample code to do what you want: http://www.chinhdo.com/20080515/chunking/

So what you could do is take this method and create an extension method.

Extension method sample:

static class ListExtension
{
    public static List<List<T>> BreakIntoChunks<T>(this List<T> list, int chunkSize)
    {
        if (chunkSize <= 0)
        {
            throw new ArgumentException("chunkSize must be greater than 0.");
        }

        List<List<T>> retVal = new List<List<T>>();

        while (list.Count > 0)
        {
            int count = list.Count > chunkSize ? chunkSize : list.Count;
            retVal.Add(list.GetRange(0, count));
            list.RemoveRange(0, count);
        }

        return retVal;
    }
}

You could try the approach shown in this answer to this similar question.

public static class GroupingExtension
{
    public static IEnumerable<IEnumerable<T>> Grouped<T>(
        this IEnumerable<T> input,
        int groupCount)
    {
        if (input == null) throw new ArgumentException("input");
        if (groupCount < 1) throw new ArgumentException("groupCount");

        IEnumerator<T> e = input.GetEnumerator();

        while (true)
        {
            List<T> l = new List<T>();
            for (int n = 0; n < groupCount; ++n)
            {
                if (!e.MoveNext())
                {
                    if (n != 0)
                    {
                        yield return l;
                    }
                    yield break;
                }
                l.Add(e.Current);
            }
            yield return l;
        }
    }
}

Use like this:

List<int> l = new List<int>{89, 67, 34, 11, 34};
foreach (IEnumerable<int> group in l.Grouped(2)) {
    string s = string.Join(", ", group.Select(x => x.ToString()).ToArray());
    Console.WriteLine(s);
}

Result:

89, 67
34, 11
34

Need Your Help

apply svn patch to git repository

git svn patch

Ok, I've tried all answers i could find on stackoverflow, but apparently none seem to be able to solve my problem. I want to apply a patch made by SVN to a git repository. Apparently the easiest wa...

Run multiple tests in one class in parallel in multiple instances of browsers using testNG

selenium webdriver testng

Please tell me sample code for the fallowing scenario using Web-driver + TestNG framework.