Bagaimana cara menggabungkan daftar daftar dengan jenis item yang sama ke satu daftar item?

210

Pertanyaannya membingungkan, tetapi jauh lebih jelas seperti yang dijelaskan dalam kode berikut:

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

Tidak yakin apakah mungkin dengan menggunakan C # LINQ atau Lambda?

Pada dasarnya, bagaimana saya bisa menggabungkan atau " meratakan " daftar daftar?

David.Chu.ca
sumber

Jawaban:

456

Gunakan metode ekstensi SelectMany

list = listOfList.SelectMany(x => x).ToList();
JaredPar
sumber
73
Saya ingin tahu berapa banyak orang yang telah menulis ekstensi "Ratakan" sendiri tanpa menyadari bagaimana SelectMany bekerja?
James Schek
1
Mengapa x => x diperlukan agar ini berfungsi? Saya biasanya melihat hal-hal seperti x => x +1 tetapi tidak x => x.
SwimBikeRun
9
@SwimBikeRun SelectMany digunakan untuk mengambil IEnumerable dari TSources, mengubah setiap TSource dalam daftar menjadi IEnumerable dari TResults, kemudian menggabungkan semua IEnumerables menjadi satu besar. Dalam hal ini Anda memiliki daftar daftar untuk memulai, jadi jika Anda ingin menyatukannya, fungsi untuk memetakan dari TSource (yang merupakan IEnumerable dari TResults) ke IEnumerable dari TResults adalah fungsi identitas (x => x). Ini benar-benar hanya kasus khusus di mana Anda tidak perlu langkah ekstra untuk mengubah setiap TSource menjadi daftar, karena sudah daftar.
Sean
@JaredPar dapatkah kita menerapkan logika ini ke daftar <daftar <daftar <T> >>?
Tk1993
4
@TusharKukreti Tentu, cukup gunakanlist.SelectMany(x => x.SelectMany(y => y)).ToList();
Brandon Kramer
13

Inilah versi sintaksis terintegrasi C #:

var items =
    from list in listOfList
    from item in list
    select item;
Joe Chung
sumber
Sedikit membingungkan, tapi menyenangkan. Bagaimana ini var items = from item in (dari daftar di listOflist pilih daftar) pilih item
David.Chu.ca
4
'Double from' sama dengan SelectMany ... SelectMany mungkin yang paling kuat dari metode LINQ (atau operator kueri). Untuk mengetahui alasannya, Google "LINQ SelectMany Monad" dan Anda akan menemukan lebih dari yang ingin Anda ketahui tentangnya.
Richard Anthony Hein
3
Jangan sertakan tanda kutip ketika googling "LINQ SelectMany Monad" atau itu hanya akan mengarahkan Anda kembali ke sini.
Oxin
12

Maksudmu ini?

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

Hasil dalam: 9 9 9 1 2 3 4 5 6

IRBMe
sumber
Atau Anda bisa menggunakan list.AddRange () alih-alih Concat () untuk menambahkan item yang digabungkan ke daftar yang ada.
dahlbyk
1

Untuk List<List<List<x>>>dan seterusnya, gunakan

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

Ini telah diposting dalam komentar, tetapi itu layak mendapat jawaban terpisah menurut pendapat saya.

Arman McHitarian
sumber