views:

561

answers:

4

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.

+1  A: 

I know in C# there is the yield operator for loops. Just iterate and yield return each sub item recursively. Apparently, there is no yield for VB, sorry.

Daniel A. White
Would love to.... Unfortunately ... VB.Net 2008 :( one of it's few failings is the lack of such an operator.
Rory Becker
+12  A: 

Are you looking for SelectMany()?

MasterList.SelectMany(master => master.SubItems)

Sorry for C#, don't know VB.

Per Erik Stendahl
Fantastic... Absolutely love StackOverflow... Close run thing between yourself and Oliver Hanappi.... Points awarded simply for slightly clearer code (By really small margin).
Rory Becker
Thanks. It's kind of hard to build rep on this site when you're competing with 100 other guys within the first 5 minutes of a question being asked. :-D
Per Erik Stendahl
FWIW VB.Net version is "MasterList.SelectMany(function(master) master.SubItems)"
Rory Becker
Incase anyone wants to see a full example in C# I posted the question before I found this one. The question number is 1222846. I'm not sure how to link to it from here.
Robin Robinson
+5  A: 

Hi!

You can achieve this by Linq with SelectMany

C# Code

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


Best Regards

Oliver Hanappi
Thanks also to you Oliver. Shame I couldn't split the points... UpVoted you anyway though. :)
Rory Becker
No problem ^^ At least I can leave comments now :)
Oliver Hanappi
+3  A: 

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).

Justice
+1 for background, although in a way Aggregate and SelectMany are similar, in that they execute a function a number of times, depending on the length of the input list, and return a single object (which happens to be another list for SelectMany, but Aggregate could return a list too). The real opposite of Aggregate is normally called Unfold, and there is no function for that in the BCL yet.
Daniel Earwicker
That's true, fold and unfold are inverses, but I meant something slightly different with the word 'opposite' - namely, Aggregate takes many and combines into one, while SelectMany takes each one and uncombines into many. In addition, I would disagree that SelectMany returns a single object - while true in one sense, it's not true in the sense of the IEnumerable monad, where you have lists going to lists going to lists (as occurs with Select, Where, Take, Drop, OrderBy, GroupBy, SelectMany, etc.).
Justice
@Justice.. I'm very interested in what you have said here... It's true that at first I was drawn to Aggregate because, from a purely english point of view, it seemed as if this was what I needed. I am now curious as to what Aggregate does provide... Perhaps you could point me at a link which gives more detail... I would love to see an example. thanks again... Very useful.
Rory Becker