Como mesclar uma lista de listas com o mesmo tipo de itens em uma única lista de itens?

210

A pergunta é confusa, mas é muito mais clara, conforme descrito nos seguintes códigos:

   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 = ???

Não tem certeza se é possível usando C # LINQ ou Lambda?

Essencialmente, como concatenar ou " achatar " uma lista de listas?

David.Chu.ca
fonte

Respostas:

456

Use o método de extensão SelectMany

list = listOfList.SelectMany(x => x).ToList();
JaredPar
fonte
73
Gostaria de saber quantas pessoas escreveram sua própria extensão "Flatten" sem perceber como o SelectMany funciona?
217 James Schek
1
Por que x => x é necessário para que isso funcione? Normalmente, vejo coisas como x => x +1, mas não x => x.
SwimBikeRun 18/04/2015
9
@SwimBikeRun SelectMany é usado para pegar um IEnumerable de TSources, converter cada TSource na lista em um IEnumerable de TResults e concatenar todos esses IEnumerables em um grande. Nesse caso, você tem uma lista de listas para iniciar; portanto, se desejar concatená-las, a função para mapear de um TSource (que é um IEnumerable de TResults) para um IEnumerable de TResults é a função de identidade (x => x). Este é realmente apenas um caso especial em que você não precisa da etapa extra de transformar cada TSource em uma lista, porque já é uma lista.
Sean
@JaredPar podemos aplicar essa lógica à lista <list <list <T> >>?
Tk1993 01/03
4
@TusharKukreti Claro, basta usarlist.SelectMany(x => x.SelectMany(y => y)).ToList();
Brandon Kramer
13

Aqui está a versão da sintaxe integrada em C #:

var items =
    from list in listOfList
    from item in list
    select item;
Joe Chung
fonte
Um pouco confuso, mas legal. Como isto? var items = do item em (da lista na listaOflist selecione a lista) selecione o item
David.Chu.ca
4
O 'double from' é o mesmo que SelectMany ... SelectMany é provavelmente o mais poderoso dos métodos LINQ (ou operadores de consulta). Para saber por que, no Google "LINQ SelectMany Monad", você descobrirá mais do que deseja saber.
Richard Anthony Hein
3
Não inclua as aspas ao pesquisar no "LINQ SelectMany Monad" ou apenas o direcionará de volta para aqui.
Oxin 25/08/16
12

Você quer dizer isso?

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

Resulta em: 9 9 9 1 2 3 4 5 6

IRBMe
fonte
Ou você pode usar list.AddRange () em vez de Concat () para adicionar os itens mesclados à lista existente.
Dahlbyk
1

Para List<List<List<x>>>e assim por diante, use

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

Isso foi publicado em um comentário, mas merece uma resposta separada na minha opinião.

Arman McHitarian
fonte