Combinazione di liste in Lambda / LINQ
Domanda
Se ho una variabile di tipo IEnumerable<List<string>>
c'è un'istruzione LINQ o un'espressione lambda che posso applicare ad essa che combinerà gli elenchi che restituiscono un IEnumerable<string>
?
Soluzione
SelectMany - ovvero
IEnumerable<List<string>> someList = ...;
IEnumerable<string> all = someList.SelectMany(x => x);
Per ogni elemento in someList, questo utilizza quindi lambda " x = > & X quot; per ottenere un IEnumerable < T > per gli oggetti interni. In questo caso, ogni & Quot; x & Quot; è un elenco < T > ;, che è già IEnumerable < T > ;.
Questi vengono quindi restituiti come blocco contiguo. In sostanza, SelectMany è qualcosa di simile (semplificato):
static IEnumerable<TResult> SelectMany<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> selector) {
foreach(TSource item in source) {
foreach(TResult result in selector(item)) {
yield return result;
}
}
}
Anche se questo è un po 'semplificato.
Altri suggerimenti
Che ne dici
myStrings.SelectMany(x => x)
Non esattamente una singola chiamata di metodo, ma dovresti essere in grado di scrivere
var concatenated = from list in lists from item in list select item;
Dove "elenchi" è il tuo IEnumerable<List<string>>
e concatenato è di tipo IEnumerable<string>
.
(Tecnicamente questo è un singolo metodo chiamato a SelectMany
- non sembra che fosse tutto ciò che intendevo con la dichiarazione di apertura. Volevo solo chiarirlo nel caso qualcuno avesse confuso o commentato - mi sono reso conto dopo aver postato come avrebbe potuto leggere).
Crea un metodo semplice. Non è necessario LINQ:
IEnumerable<string> GetStrings(IEnumerable<List<string>> lists)
{
foreach (List<string> list in lists)
foreach (string item in list)
{
yield return item;
}
}
Uso dell'espressione LINQ ...
IEnumerable<string> myList = from a in (from b in myBigList
select b)
select a;
... funziona bene. : -)
b
sarà un IEnumerable<string>
e a
sarà un string
.
Ecco un'altra comprensione della query LINQ.
IEnumerable<string> myStrings =
from a in mySource
from b in a
select b;