Comment fusionner une liste de listes avec le même type d'éléments à une seule liste d'éléments?

210

La question prête à confusion, mais elle est beaucoup plus claire comme décrit dans les codes suivants:

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

Vous ne savez pas si cela est possible en utilisant C # LINQ ou Lambda?

Essentiellement, comment puis-je concaténer ou " aplatir " une liste de listes?

David.Chu.ca
la source

Réponses:

456

Utilisez la méthode d'extension SelectMany

list = listOfList.SelectMany(x => x).ToList();
JaredPar
la source
73
Je me demande combien de personnes ont écrit leur propre extension "Aplatir" sans se rendre compte du fonctionnement de SelectMany?
James Schek
1
Pourquoi x => x est-il nécessaire pour que cela fonctionne? Je vois généralement des choses comme x => x +1 mais pas x => x.
SwimBikeRun
9
@SwimBikeRun SelectMany est utilisé pour prendre un IEnumerable de TSources, convertir chaque TSource de la liste en un IEnumerable de TResults, puis concaténer tous ces IEnumerables en un seul. Dans ce cas, vous avez une liste de listes à démarrer, donc si vous voulez les concaténer, la fonction à mapper d'un TSource (qui est un IEnumerable de TResults) à un IEnumerable de TResults est la fonction d'identité (x => x). C'est vraiment juste un cas spécial où vous n'avez pas besoin de l'étape supplémentaire de transformer chaque TSource en liste, car c'est déjà une liste.
Sean
@JaredPar peut-on appliquer cette logique à lister <list <list <T> >>?
Tk1993
4
@TusharKukreti Bien sûr, utilisez simplementlist.SelectMany(x => x.SelectMany(y => y)).ToList();
Brandon Kramer
13

Voici la version de la syntaxe intégrée C #:

var items =
    from list in listOfList
    from item in list
    select item;
Joe Chung
la source
Un peu déroutant, mais agréable. Comment ce? var items = from item in (from list in listOflist select list) select item
David.Chu.ca
4
Le «double de» est le même que SelectMany ... SelectMany est probablement la plus puissante des méthodes LINQ (ou opérateurs de requête). Pour voir pourquoi, Google "LINQ SelectMany Monad" et vous découvrirez plus que vous ne voudrez en savoir.
Richard Anthony Hein
3
N'incluez pas les guillemets lors de la recherche sur "LINQ SelectMany Monad" ou cela vous redirigera simplement ici.
Oxin
12

Est-ce que tu veut dire ça?

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

Résulte en: 9 9 9 1 2 3 4 5 6

IRBMe
la source
Ou vous pouvez utiliser list.AddRange () au lieu de Concat () pour ajouter les éléments fusionnés à la liste existante.
dahlbyk
1

Pour List<List<List<x>>>et ainsi de suite, utilisez

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

Cela a été publié dans un commentaire, mais cela mérite une réponse séparée à mon avis.

Arman McHitarian
la source