188

I have a data structure like

public DespatchGroup(DateTime despatchDate, List<Products> products);

And I am trying to do...

var list = new List<DespatchGroup>();

foreach (var group in dc.GetDespatchedProducts().GroupBy(i => i.DespatchDate))
{
    // group.Values is not correct... how do I write this?
    list.Add(new DespatchGroup(group.Key, group.Values);
}

I'm obviously not understanding IGrouping as I can't see how to actually get to the data records within the group!

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
fearofawhackplanet
  • 52,166
  • 53
  • 160
  • 253
  • 1
    The edit [(Rev2)](http://stackoverflow.com/revisions/4804477/2) wasn't very constructive as it doesn't match any of the answers. – Sunny Patel May 14 '14 at 17:30

4 Answers4

217

The group implements IEnumerable<T> - In the general case, just call foreach over the group. In this case, since you need a List<T>:

list.Add(new DespatchGroup(group.Key, group.ToList());
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • So basically if we are following the essence of the question `value` is comparable to `ToList()` only there is more of an overhead there to convert it to a list as opposed to just pulling out a value – Paul C Dec 17 '14 at 15:25
  • 2
    @CodeBlend there's more overhead because they want a list. If there was a `Values` property like they imagined then they'd have to do `group.Values.ToList()`. Conversely if they accepted any enumerable instead of a list then `new DespatchGroup(group.Key, group)` would work. The overhead is from the definition of `DespachGroup` not from the way IGrouping works. – Jon Hanna Jun 19 '15 at 10:18
45

There's no Values property or similar because the IGrouping<T> itself is the IEnumerable<T> sequence of values. All you need to do in this case is convert that sequence to a list:

list.Add(new DespatchGroup(group.Key, group.ToList());
LukeH
  • 263,068
  • 57
  • 365
  • 409
  • 12
    We may also convert to an IEnumerable if we wish: `group.AsEnumerable()`. – Mateen Ulhaq Jan 28 '16 at 18:55
  • @MateenUlhaq While that is possible it is a bit redundant as IGrouping already is derived from IEnumerable. It will work in most places you would use IEnumerable without needing any kind of explicit casting/converting. – Leon Lucardie Jun 15 '21 at 15:19
41

For any selected group,you could call

var selectedGroupValues=selectedGroup.SelectMany(x=>x);
Andy
  • 49,085
  • 60
  • 166
  • 233
Bassl Kokash
  • 627
  • 5
  • 10
  • 3
    Thanks! Unlike `.Select` which will return an IGrouping<> again, `.SelectMany` will return an IEnumerable of the groupped values' type, which is what I was after. – K0D4 Oct 01 '18 at 18:53
  • I'd say only use this when there are (potentially) multiple groups selected. (aka `IEnumerable>`). Otherwise, use `toList()`, or simply cast it to `IEnumerable`. – apple apple Jan 09 '20 at 05:33
27

Just a related tip - since, as the other answers have said, the grouping is an IEnumerable, if you need to access a specific index you can use group.ElementAt(i).

This is probably obvious to a lot of people but hopefully it will help a few!

Rob H
  • 1,840
  • 16
  • 25