Come unire un elenco di elenchi con lo stesso tipo di elementi in un unico elenco di elementi?


210

La domanda è confusa, ma è molto più chiara come descritto nei seguenti codici:

   List<List<T>> listOfList;
   // add three lists of List<T> to listOfList, for example
   /* listOfList = new {
        { 1, 2, 3}, // list 1 of 1, 3, and 3
        { 4, 5, 6}, // list 2
        { 7, 8, 9}  // list 3
        };
   */
   List<T> list = null;
   // how to merger all the items in listOfList to list?
   // { 1, 2, 3, 4, 5, 6, 7, 8, 9 } // one list
   // list = ???

Non sei sicuro che sia possibile utilizzando C # LINQ o Lambda?

In sostanza, come posso concatenare o " appiattire " un elenco di elenchi?

Risposte:


456

Utilizzare il metodo di estensione SelectMany

list = listOfList.SelectMany(x => x).ToList();

73
Mi chiedo quante persone hanno scritto la propria estensione "Flatten" non rendendosi conto di come SelectMany funzioni?
James Schek,

1
Perché x => x è necessario affinché questo funzioni? Di solito vedo cose come x => x +1 ma non x => x.
SwimBikeRun

9
@SwimBikeRun SelectMany viene utilizzato per prendere un IEnumerable di TSources, convertire ogni TSource nell'elenco in un IEnumerable di TResults, quindi concatenare tutti quegli IEnumerable in uno unico. In questo caso hai un elenco di elenchi da avviare, quindi se vuoi concatenarli la funzione da mappare da un TSource (che è un IEnumerable di TResults) a un IEnumerable di TResults è la funzione di identità (x => x). Questo è davvero solo un caso speciale in cui non è necessario il passaggio aggiuntivo di trasformare ogni TSource in un elenco, perché è già un elenco.
Sean,

@JaredPar possiamo applicare questa logica all'elenco <list <list <T> >>?
Tk1993,

4
@TusharKukreti Certo, basta usarelist.SelectMany(x => x.SelectMany(y => y)).ToList();
Brandon Kramer il

13

Ecco la versione della sintassi integrata C #:

var items =
    from list in listOfList
    from item in list
    select item;

Un po 'confuso, ma carino. Come questo? var items = dalla voce in (dalla lista nella listaOplist seleziona la lista) seleziona la voce
David.Chu.ca,

4
Il "doppio da" è lo stesso di SelectMany ... SelectMany è probabilmente il più potente dei metodi LINQ (o operatori di query). Per capire perché, "LINQ SelectMany Monad" di Google scoprirai più di quello che vorresti sapere.
Richard Anthony Hein,

3
Non includere le virgolette quando si cerca su Google "LINQ SelectMany Monad" o ti reindirizzerà qui.
Oxin,

12

Intendi questo?

var listOfList = new List<List<int>>() {
    new List<int>() { 1, 2 },
    new List<int>() { 3, 4 },
    new List<int>() { 5, 6 }
};
var list = new List<int> { 9, 9, 9 };
var result = list.Concat(listOfList.SelectMany(x => x));

foreach (var x in result) Console.WriteLine(x);

Risultati in: 9 9 9 1 2 3 4 5 6


Oppure puoi usare list.AddRange () invece di Concat () per aggiungere gli elementi uniti all'elenco esistente.
Dahlbyk,

1

Per List<List<List<x>>>e così via, utilizzare

list.SelectMany(x => x.SelectMany(y => y)).ToList();

Questo è stato pubblicato in un commento, ma a mio avviso merita una risposta separata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.