4

Looking for a way to group in sets of n elements with LINQ.

I.e:

{1,2,3,4,5,6,7,8,9}:

  • Grouped By 2: {{1,2},{3,4},{5,6},{7,8},{9}}
  • Grouped By 3: {{1,2,3},{4,5,6},{7,8,9}}
  • Grouped By 4: {{1,2,3,4},{5,6,7,8},{9}}
  • Etc...

Only way I can think of doing something like this at the moment is by using an anonymous type to generate a group index, then grouping by that index. I'm looking for a cleaner solution if possible.

Example:

int groupSize = n;
int groupCount = 0;
int groupNum = 0;

IEnumerable<T> items;
IEnumerable<IGrouping<int,T>> groups = items
    .Select(i => new 
    {
      Index = ((groupCount++) % groupSize == 0) ? groupNum++ : groupNum,
      Item = i
    })
    .GroupBy(c => c.Index, d => d.Item);

I'd like to avoid something this nasty if possible.

Aren
  • 54,668
  • 9
  • 68
  • 101
  • It would be awesome if there's a better way, but I don't think there is. – Jeff Schumacher Jun 04 '10 at 20:07
  • I mean, I could always write the above as an extension function, I just don't know how the delayed execution would work with something like that. I'd prefer things to be as LINQ'y as possible :) – Aren Jun 04 '10 at 20:10

2 Answers2

6
var values = new []{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };

groups = values.Select((v, i) => new { index = i, value = v })
    .GroupBy(k => k.index / n, e => e.value);
Yuriy Faktorovich
  • 67,283
  • 14
  • 105
  • 142
0

I've answered a similar question here. It still uses an anonymous type, but I don't think it's as "nasty" as your example.

Community
  • 1
  • 1
GWB
  • 2,575
  • 2
  • 23
  • 28