2009-06-30 10 views
18

Dada ....¿Cómo puedo agregar múltiples IEnumerables de T

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

me gustaría que una única IEnumerable (Of T) que iterar a través de todos los subelementos de todos MasterItems en MasterList

lo haría me gusta pensar que hay una instalación de Linq para hacer esto, o un método de extensión que estoy pasando por alto. Necesito un mecanismo que funcione en VB9 (2008) y, por lo tanto, no use Rendimiento.

Respuesta

27

¿Está buscando SelectMany()?

MasterList.SelectMany(master => master.SubItems) 

Lo siento por C#, no sé VB.

+0

Fantástico ... Amor por completo StackOverflow ... Cierra la cosa entre tú y Oliver Hanappi .... Puntos otorgados simplemente por código ligeramente más claro (Por un margen realmente pequeño) –

+0

Gracias. Es un poco difícil construir una reputación en este sitio cuando estás compitiendo con otros 100 tipos dentro de los primeros 5 minutos de una pregunta se le preguntó. :-D –

+2

FWIW versión VB.Net es "MasterList.SelectMany (función (maestro) maestro.SubItems)" –

1

Sé en C# existe el operador yield para bucles. Simplemente itere y yield return cada sub artículo recursivamente. Aparentemente, no hay yield para VB, lo siento.

+1

Me encantaría .... Lamentablemente ... VB.Net 2008 :(uno de sus pocos defectos es la falta de un operador de este tipo. –

8

se puede lograr esto mediante LINQ con SelectMany

C# Código

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


Saludos

+0

Gracias también a ti Oliver. Es una pena no poder dividir los puntos ... UpVoted de todos modos.:) –

+0

No hay problema ^^ Al menos puedo dejar comentarios ahora :) –

8

Enumerable.SelectMany es la clave para la IEnumerable mónada, al igual que su equivalente Haskell, concatMap, es la clave de la mónada de Haskell.

Como resultado, su pregunta va directamente al corazón de un aspecto profundo de la informática.

Querrá tener cuidado con su fraseo, porque Aggregate significa algo muy diferente de SelectMany - incluso lo contrario. Aggregate combina IEnumerable de valores en un solo valor (posiblemente de otro tipo), mientras que SelectManyun combina valores de IEnumerable en aún más valores (posiblemente de otro tipo).

+0

+1 de fondo, aunque en cierto modo Aggregate y SelectMany son similares, ya que ejecutan una función varias veces, dependiendo de la longitud de la entrada enumera y devuelve un solo objeto (que pasa a ser otra lista para SelectMany, pero Aggregate podría devolver una lista también). El verdadero opuesto de Aggregate normalmente se denomina Desdoblamiento, y todavía no hay una función para eso en el BCL. –

+0

Eso es cierto, doblar y desplegar son inversos, pero quise decir algo ligeramente diferente con la palabra "opuesto", es decir, Aggregate toma muchos y se combina en uno, mientras que SelectMany los toma y descompone en muchos. Además, no estoy de acuerdo con que SelectMany devuelva un solo objeto: si bien es cierto en cierto sentido, no es cierto en el sentido de la mónada IEnumerable, donde tiene listas que van a listas que van a listas (como ocurre con Seleccionar, Dónde, Tomar, Drop, OrderBy, GroupBy, SelectMany, etc.). – yfeldblum

+0

@Justice ... Estoy muy interesado en lo que ha dicho aquí ... Es cierto que al principio me sentí atraído por Aggregate porque, desde un punto de vista puramente inglés, parecía que esto era lo que necesitaba. Ahora tengo curiosidad sobre lo que agrega Aggregate ... Tal vez podrías indicarme un enlace que brinde más detalles ... Me encantaría ver un ejemplo. gracias de nuevo ... Muy útil. –

3

sólo para proporcionar respuestas verdaderas 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) 

Todos ellos compilan a la misma IL, excepto children2 requiere el equivalente de Function(master, child) child.

Cuestiones relacionadas