Как объединить несколько IEnumerables из T

Дано....

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

Я хотел бы один IEnumerable (Of T), который будет перебирать все подэлементы всех MasterItems в MasterList

Я хотел бы думать, что есть средство Linq, чтобы сделать это, или метод расширения, который я пропускаю. Мне нужен механизм, который работает в VB9 (2008) и, следовательно, не использует доходность.

Ответы на вопрос(5)

Просто, чтобы предоставить истинные ответы VB.NET:

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

Все они компилируются до одного и того же IL, кромеchildren2 требует эквивалентаFunction(master, child) child.

Enumerable.SelectMany это ключ кIEnumerable монада, как и ее эквивалент Хаскелла,concatMap, является ключом к монаде списка Haskell.

Как выясняется, ваш вопрос направлен прямо в глубину глубокого аспекта информатики.

Вы хотите быть осторожным с вашей формулировкой, потому чтоAggregate означает что-то очень отличное отSelectMany - даже наоборот.Aggregate сочетает в себеIEnumerable значений в одно значение (возможно, другого типа), в то время какSelectMany unсочетает в себеIEnumerable значений в еще большее количество значений (возможно, другого типа).

 01 июл. 2009 г., 15:14
+1 для фона, хотя в некотором роде Aggregate и SelectMany похожи в том, что они выполняют функцию несколько раз, в зависимости от длины списка ввода, и возвращают один объект (который оказывается другим списком для SelectMany, но Агрегат может вернуть список тоже). Реальная противоположность Aggregate обычно называется Развернуть, и в BCL пока нет функции для этого.
 Rory Becker02 июл. 2009 г., 12:13
@ Справедливость ... Меня очень интересует то, что вы сказали здесь ... Правда, сначала меня тянуло к Aggregate, потому что с чисто английской точки зрения казалось, что это то, что мне нужно. Теперь мне любопытно, что Aggregate предоставляет ... Возможно, вы могли бы указать мне ссылку, которая дает более подробную информацию ... Я хотел бы увидеть пример. Еще раз спасибо ... Очень полезно.
 01 июл. 2009 г., 15:22
Это правда, сложить и развернуть являются обратными, но я имел в виду что-то немного другое со словом «противоположный» а именно, Aggregate берет много и объединяет в одно, тогда как SelectMany берет каждое и объединяет во многие. Кроме того, я не согласен с тем, что SelectMany возвращает один объект - хотя в некотором смысле это правда, это не так в смысле монады IEnumerable, где у вас есть списки, идущие в списки, идущие в списки (как это происходит с Select, Where, Take, Drop, OrderBy, GroupBy, SelectMany и т. Д.).
Решение Вопроса

Вы ищете SelectMany ()?

MasterList.SelectMany(master => master.SubItems)

Извините за C #, не знаю VB.

 30 июн. 2009 г., 14:12
Благодарю. На этом сайте сложно создать репутацию, когда вы соревнуетесь со 100 другими парнями в течение первых 5 минут после того, как был задан вопрос. :-D
 Rory Becker30 июн. 2009 г., 13:56
Фантастика ... Абсолютно люблю StackOverflow ... Близко бегите между вами и Оливером Ханаппи .... Очки начисляются просто за чуть более четкий код (с очень небольшим отрывом).
 03 авг. 2009 г., 17:12
Если кто-то захочет увидеть полный пример на C #, я разместил вопрос еще до того, как нашел этот. Номер вопроса 1222846. Я не знаю, как с ним связаться.
 Rory Becker30 июн. 2009 г., 14:14
Версией FWIW VB.Net является «MasterList.SelectMany (функция (мастер) master.SubItems)».

Вы можете достичь этого с помощью Linq с SelectMany

Код C #

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


С уважением

 Rory Becker30 июн. 2009 г., 14:06
Спасибо также тебе, Оливер. Жаль, что я не смог разделить баллы ... В любом случае, вы проголосовали за вас. :)
 30 июн. 2009 г., 14:31
Нет проблем ^^ По крайней мере, я могу оставлять комментарии сейчас :)

Я знаю, в C # естьyield оператор для циклов. Просто повторяем иyield return каждый подпункт рекурсивно. Видимо, нетyield для VB, извините.

 Rory Becker30 июн. 2009 г., 13:50
Очень хотелось бы ... К сожалению ... VB.Net 2008 :( Одним из немногих недостатков является отсутствие такого оператора.

Ваш ответ на вопрос