25

I cannot find a way to make this work and hoping someone has an idea. A simplified example would be having a list of say integers 1-100, i want to group every 3 rows so the result would be 1,2,3 in first group then 4,5,6 in next group etc. I know how to get every nth record but what I need is all the records so I can then aggregate them, using first, last, sum, max, etc.

Thanks!

RBear
  • 383
  • 2
  • 5
  • 13
  • possible duplicate of [Split List into Sublists with LINQ](http://stackoverflow.com/questions/419019/split-list-into-sublists-with-linq) – nawfal Feb 18 '13 at 10:41

3 Answers3

44

This example should work for querying non-numeric collections. It projects an index into the object to be grouped, and then removes it again during the grouping.

var studentQuery2 = students
    .Select((student, index) => new {student, index})
    .GroupBy(g => g.index / 3, i => i.student);
Scott Ivey
  • 40,768
  • 21
  • 80
  • 118
  • Thanks also, but where does index come from? – RBear May 13 '09 at 21:05
  • i was hoping the select would project its index into the query. Looks like it doesn't. I'll update the example accordingly - so that you can use it with non-int based collections. – Scott Ivey May 13 '09 at 21:19
  • 7
    FYI, in the next version of the framework there will be a "zip join" extension method. If you zip a query result with an infinite sequence of integers, you get an indexed sequence. See my recent blog article on this subject for details. – Eric Lippert May 13 '09 at 21:25
  • nice - i'll definitely be looking forward to that feature. – Scott Ivey May 13 '09 at 21:28
  • @eric - thanks, im gonna try that out. Is that faster than using the select with index into a new type? – RBear May 14 '09 at 01:32
31
var q = Enumerable.Range(0, 100).GroupBy(x => x/3);

Am I missing something?

idursun
  • 6,261
  • 1
  • 37
  • 51
  • 1
    Being pedantic - Enumerable.Range(1, 100) since he wanted to start at 1. – Winston Smith May 14 '09 at 08:52
  • If the first number is 0, it works fine. But if the first number is 1, the first group has one less element. For example {0,1,2}, {3,4,5}, but {1,2}, {3,4,5}. How to fix this? – Damn Vegetables Jul 24 '17 at 08:00
2

How about a simpler approach:

var index = 0;
var grpOf3s = students.GroupBy(x => index++ / 3);

Update: If you are using the Key value of the group item then you will need to convert the group enumerable to a list. Otherwise you will get a different Key every time it is accessed.

var index = 0;
var grpOf3s = students.GroupBy(x => index++ / 3).ToList();
Sudeep
  • 349
  • 2
  • 14