Buat kamus pada daftar dengan pengelompokan

106

Saya memiliki objek berikut dalam daftar:

public class DemoClass
{
    public int GroupKey { get; set; }
    public string DemoString { get; set; }
    public object SomeOtherProperty { get; set; }
}

Sekarang, saya ingin membuat kamus berikut darinya:

Dictionary<int, List<DemoClass>>

Saya ingin mengelompokkan List<DemoClass>berdasarkan properti GroupKey, tetapi saya tidak mengerti bagaimana hal ini dilakukan dan beberapa bantuan.

Setelah berpikir sedikit, saya mencapai perilaku yang dibutuhkan dengan:

var groupedDemoClasses = from demoClass in mySepcialVariableWhichIsAListOfDemoClass
                            group demoClass by demoClass.GroupKey
                            into groupedDemoClass
                            select groupedDemoClass;
var neededDictionary = groupedDemoClass.ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

Tapi, apakah ada cara untuk membuatnya menjadi satu pernyataan?

Andreas Niedermair
sumber

Jawaban:

88
var groupedDemoClasses = (from demoClass in mySepcialVariableWhichIsAListOfDemoClass
                          group demoClass by demoClass.GroupKey
                          into groupedDemoClass
                          select groupedDemoClass).ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

Yang ini akan berhasil !!!

Prashant Cholachagudda
sumber
198

Hanya untuk membuat saran mquander menjadi nyata:

var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
                             .GroupBy(x => x.GroupKey)
                             .ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

Anda akan membuatnya lebih pendek jika Anda menggunakan nama variabel yang lebih pendek juga, tentu saja :)

Namun, dapatkah saya menyarankan agar Pencarian mungkin lebih sesuai? Pencarian pada dasarnya adalah kamus dari kunci ke IEnumerable<T>- kecuali Anda benar - benar membutuhkan nilai sebagai daftar, itu membuat kode lebih pendek (dan lebih efisien) dengan panggilan ToLookup :

var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
                             .ToLookup(x => x.GroupKey);
Jon Skeet
sumber
1
Saya pikir pencarian berkinerja tidak begitu baik, dibandingkan dengan kamus yang dibuat, dalam lingkungan jangka panjang, karena itu membangun hasil segar untuk setiap permintaan ... tolong perbaiki saya, jika saya salah!
Andreas Niedermair
Tidak, ini membuat seluruh pencarian. Secara umum, ToXXX tidak menggunakan eksekusi yang ditangguhkan.
Jon Skeet
1
(Anda mungkin berpikir tentang Pengelompokan, yang memang ditangguhkan.)
Jon Skeet
1
Jika saya tidak begitu dengki, saya akan memilih Anda. Datang untuk Linq, tinggal untuk struktur data yang belum pernah saya dengar!
Chris McCall
2
@sasikt: Modelnya adalah Anda dapat mencari apa saja , dan Anda hanya mendapatkan koleksi kosong jika kuncinya tidak ada. Itu seringkali lebih berguna daripada pendekatan TryGetValue, IMO.
Jon Skeet
6

Anda sudah membuatnya menjadi satu baris. Letakkan saja ToDictionarydi akhir baris pertama Anda. Jika Anda ingin membuatnya lebih pendek, gunakan sintaks komposisi fungsional daripada sintaks kueri.

Mqp
sumber
3

Saya akan sedikit keluar dari topik di sini, tetapi saya sampai di utas ini karena saya sedang mencari cara untuk membuat kamus dari kamus di Linq, dan percakapan di sini membawa saya ke jawaban ...

Anda dapat menggunakan linq untuk membuat kamus multi-level, yang berguna untuk skenario di mana Anda memiliki lebih dari 1 kunci atau dimensi yang ingin Anda telusuri. Caranya adalah dengan membuat pengelompokan kemudian mengubahnya menjadi kamus, sebagai berikut:

  Dim qry = (From acs In ActualSales _
             Group By acs.ProductID Into Group _
             Select ProductID, Months = Group.ToDictionary(Function(c) c.Period) _
            ).ToDictionary(Function(c) c.ProductID)

Kueri yang dihasilkan dapat digunakan sebagai berikut:

 If qry.ContainsKey(_ProductID) Then
      With qry(_ProductID)
          If .Months.ContainsKey(_Period) Then
             ...
          End If
      End With
 End If

Semoga ini bermanfaat bagi siapa pun yang membutuhkan pertanyaan semacam ini.

Menandai
sumber