Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I Aggregate multiple IEnumerables of T

Given....

Public MasterList as IEnumerable(Of MasterItem)
Public Class MasterItem(Of T) 
    Public SubItems as IEnumerable(Of T)
End Class 

I would like a single IEnumerable(Of T) which will iterate through all SubItems of all MasterItems in MasterList

I would like to think that there is a Linq facility to do this, or an extension method I am overlooking. I need a mechanism that works in VB9 (2008) and hence does not use Yield.

like image 546
Rory Becker Avatar asked Jun 30 '09 11:06

Rory Becker


4 Answers

Are you looking for SelectMany()?

MasterList.SelectMany(master => master.SubItems)

Sorry for C#, don't know VB.

like image 86
Per Erik Stendahl Avatar answered Nov 11 '22 11:11

Per Erik Stendahl


You can achieve this by Linq with SelectMany

C# Code

masterLists.SelectMany(l => l.SubItems);


Best Regards

like image 22
Oliver Hanappi Avatar answered Nov 11 '22 12:11

Oliver Hanappi


Enumerable.SelectMany is the key to the IEnumerable monad, just as its Haskell equivalent, concatMap, is the key to Haskell's list monad.

As it turns out, your question goes right to the heart of a deep aspect of computer science.

You will want to be careful with your phrasing, because Aggregate means something very different from SelectMany - even the opposite. Aggregate combines an IEnumerable of values into a single value (of possibly another type), while SelectMany uncombines an IEnumerable of values into even more values (of possibly another type).

like image 8
yfeldblum Avatar answered Nov 11 '22 11:11

yfeldblum


Just to provide true VB.NET answers:

' Identical to Per Erik Stendahl's and Oliver Hanappi's C# answers
Dim children1 = MasterList.SelectMany(Function(master) master.SubItems)

' Using VB.NET query syntax
Dim children2 = From master In MasterList, child in master.SubItems Select child

' Using Aggregate, as the question title referred to
Dim children3 = Aggregate master In MasterList Into SelectMany(master.SubItems)

These all compile down to the same IL, except children2 requires the equivalent of Function(master, child) child.

like image 3
Mark Hurd Avatar answered Nov 11 '22 12:11

Mark Hurd