Jak scalić listę list z tym samym typem przedmiotów do pojedynczej listy przedmiotów?

209

Pytanie jest mylące, ale jest o wiele bardziej jasne, jak opisano w następujących kodach:

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

Nie jesteś pewien, czy jest to możliwe przy użyciu C # LINQ lub Lambda?

Zasadniczo, jak mogę połączyć lub „ spłaszczyć ” listę list?

David.Chu.ca
źródło

Odpowiedzi:

455

Użyj metody rozszerzenia SelectMany

list = listOfList.SelectMany(x => x).ToList();
JaredPar
źródło
73
Zastanawiam się, ilu ludzi napisało własne rozszerzenie „Spłaszcz”, nie zdając sobie sprawy, jak działa SelectMany?
James Schek
1
Dlaczego x => x jest potrzebne, aby to zadziałało? Zwykle widzę rzeczy takie jak x => x +1, ale nie x => x.
SwimBikeRun 18.04.2015
9
@SwimBikeRun SelectMany służy do pobierania IEnumerable TSources, konwertowania każdego TSource z listy na IEnumerable TResults, a następnie łączenia wszystkich IEnumerable w jeden duży. W tym przypadku masz listę list do uruchomienia, więc jeśli chcesz je połączyć, funkcją mapowania z TSource (która jest IEnumerable z TResults) do IEnumerable z TResults jest funkcja tożsamości (x => x). Jest to tak naprawdę szczególny przypadek, w którym nie potrzebujesz dodatkowego kroku, aby zamienić każde źródło TS w listę, ponieważ jest to już lista.
Sean
@JaredPar czy możemy zastosować tę logikę do listy <lista <lista <T> >>?
Tk1993
4
@TusharKukreti Pewnie, po prostu użyjlist.SelectMany(x => x.SelectMany(y => y)).ToList();
Brandon Kramer
13

Oto zintegrowana wersja składni C #:

var items =
    from list in listOfList
    from item in list
    select item;
Joe Chung
źródło
Trochę mylące, ale miłe. Jak to? var items = z pozycji w (z listy w liście Wybierz listę) wybierz pozycję
David.Chu.ca
4
„Podwójne z” jest takie samo jak SelectMany ... SelectMany jest prawdopodobnie najpotężniejszą z metod LINQ (lub operatorów zapytań). Aby zobaczyć, dlaczego, Google „LINQ SelectMany Monad” i odkryjesz więcej, niż chcesz o tym wiedzieć.
Richard Anthony Hein
3
Nie umieszczaj cudzysłowów podczas przeglądania Google „LINQ SelectMany Monad”, ponieważ po prostu przekieruje Cię z powrotem tutaj.
Oxin,
12

Masz na myśli to?

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

Prowadzi do: 9 9 9 1 2 3 4 5 6

IRBMe
źródło
Lub możesz użyć list.AddRange () zamiast Concat (), aby dodać scalone elementy do istniejącej listy.
dahlbyk
1

Do List<List<List<x>>>i tak dalej, użytkowania

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

Zostało to opublikowane w komentarzu, ale moim zdaniem zasługuje na osobną odpowiedź.

Arman McHitarian
źródło