Cara mendapatkan nilai dari IGrouping

211

Saya punya pertanyaan tentang IGroupingdan Select()metode.

Katakanlah saya punya IEnumerable<IGrouping<int, smth>>cara seperti ini:

var groups = list.GroupBy(x => x.ID);

dimana lista List<smth>.

Dan sekarang saya perlu memberikan nilai masing-masing IGroupingke daftar lain dengan beberapa cara:

foreach (var v in structure)
{
    v.ListOfSmth = groups.Select(...); // <- ???
}

Adakah yang bisa menyarankan cara mendapatkan nilai ( List<smth>) dari IGrouping<int, smth>dalam konteks seperti itu?

Illia Ratkevych
sumber
ID biasanya merupakan bidang identitas yang harus unik, yang akan membuat pengelompokan olehnya tidak berguna, jika Anda hanya ingin menghapus data duplikat cobalah Distinct () sebagai gantinya. jika itu list.GroupBy (x => x.SubID) maka akan masuk akal untuk menggunakan pengelompokan tetapi dalam kasus itu Anda kemungkinan besar ingin mempertahankan pengelompokan dan foreach (var grp dalam grup) {grp.ToList () ; } akan melakukan itu
MikeT

Jawaban:

277

Sejak IGrouping<TKey, TElement>diterapkan IEnumerable<TElement>, Anda dapat menggunakannya SelectManyuntuk menggabungkan semuanya IEnumerablesmenjadi satu IEnumerable:

List<smth> list = new List<smth>();
IEnumerable<IGrouping<int, smth>> groups = list.GroupBy(x => x.id);
IEnumerable<smth> smths = groups.SelectMany(group => group);
List<smth> newList = smths.ToList();
Matt Smith
sumber
3
Bukankah itu sama dengan "orderBy" yang normal? List <smth> newList = list .OrderBy (x => x.id) .ToList ();
MorgoZ
@MorgoZ, pertanyaannya adalah tentang mengambil groupsdan kembali ke daftar datar.
Matt Smith
3
@MorgoZ, OrderBy(x => x.id)akan mengurutkannya dalam urutan naik dengan ID. Bandingkan dengan ini .GroupBy(x => x.id).SelectMany(group => group), yang akan mengurutkannya berdasarkan urutan tampilan ID pertama. Jika ID asli berada dalam urutan: [1,3,2,2,2,3,0], maka mengelompokkannya dan kemudian meratakannya dalam satu daftar akan menempatkan ID tersebut dalam urutan baru: [1,3,3, 2,2,2,0].
Pi Fisher
2
Ini tidak berfungsi untuk saya .. dikatakan bahwa jenisnya tidak dapat disimpulkan oleh penggunaan
Revious
3
jenis tidak dapat disimpulkan oleh penggunaan
Leo Gurdian
34
foreach (var v in structure) 
{     
    var group = groups.Single(g => g.Key == v. ??? );
    v.ListOfSmth = group.ToList();
}

Pertama, Anda perlu memilih grup yang diinginkan. Kemudian Anda dapat menggunakan ToListmetode pada grup. The IGroupingadalah IEnumerablenilai-nilai.

Tim Cools
sumber
17

Versi yang lebih jelas dari jawaban di atas:

IEnumerable<IGrouping<int, ClassA>> groups = list.GroupBy(x => x.PropertyIntOfClassA);

foreach (var groupingByClassA in groups)
{
    int propertyIntOfClassA = groupingByClassA.Key;

    //iterating through values
    foreach (var classA in groupingByClassA)
    {
        int key = classA.PropertyIntOfClassA;
    }
}
Bronek
sumber
Kurasa tidak, setidaknya untuk saat ini.
snr
15

Dari definisi IGrouping:

IGrouping<out TKey, out TElement> : IEnumerable<TElement>, IEnumerable

Anda bisa beralih melalui elemen seperti ini:

IEnumerable<IGrouping<int, smth>> groups = list.GroupBy(x => x.ID)
foreach(IEnumerable<smth> element in groups)
{
//do something
}
pengguna1275513
sumber
1
yang beralih melalui dia mengelompokkan bukan item dalam grup
MikeT
1
Oh, kesalahan saya, maka: 'foreach (pertanda p dalam grup.
Pilih Banyak