Misalkan jika kita memiliki kelas seperti:
class Person {
internal int PersonID;
internal string car;
}
Sekarang saya memiliki daftar kelas ini: List<Person> persons;
Sekarang daftar ini dapat memiliki beberapa instance dengan yang sama PersonID
, misalnya:
persons[0] = new Person { PersonID = 1, car = "Ferrari" };
persons[1] = new Person { PersonID = 1, car = "BMW" };
persons[2] = new Person { PersonID = 2, car = "Audi" };
Apakah ada cara saya dapat mengelompokkan berdasarkan PersonID
dan mendapatkan daftar semua mobil yang dimilikinya?
Misalnya, hasil yang diharapkan adalah
class Result {
int PersonID;
List<string> cars;
}
Jadi setelah pengelompokan, saya akan mendapatkan:
results[0].PersonID = 1;
List<string> cars = results[0].cars;
result[1].PersonID = 2;
List<string> cars = result[1].cars;
Dari apa yang telah saya lakukan sejauh ini:
var results = from p in persons
group p by p.PersonID into g
select new { PersonID = g.Key, // this is where I am not sure what to do
Bisakah seseorang tolong tunjukkan saya ke arah yang benar?
Count
dan diSum
sini stackoverflow.com/questions/3414080/…Jawaban:
Tentu - Anda pada dasarnya ingin:
Atau sebagai ekspresi non-permintaan:
Pada dasarnya isi grup (bila dilihat sebagai
IEnumerable<T>
) adalah urutan nilai apa pun yang ada dalam proyeksi (p.car
dalam hal ini) hadir untuk kunci yang diberikan.Untuk lebih lanjut tentang cara
GroupBy
kerjanya, lihat posting Edulinq saya pada topik .(Saya telah berganti nama
PersonID
menjadiPersonId
di atas, untuk mengikuti konvensi penamaan .NET )Atau, Anda dapat menggunakan
Lookup
:Anda kemudian dapat memperoleh mobil untuk setiap orang dengan sangat mudah:
sumber
.GroupBy(p => new {p.Id, p.Name}, p => p, (key, g) => new { PersonId = key.Id, PersonName = key.Name, PersonCount = g.Count()})
dan Anda akan mendapatkan semua orang yang muncul dengan Id, Nama, dan sejumlah kejadian untuk setiap orang.sumber
sumber
Anda juga dapat Coba ini:
sumber
mencoba
atau
untuk memeriksa apakah ada orang yang mengulang dalam daftar Anda, cobalah
sumber
Saya telah membuat contoh kode kerja dengan Query Syntax dan Method Syntax. Saya harap ini membantu yang lain :)
Anda juga dapat menjalankan kode pada .Net Fiddle di sini:
Inilah hasilnya:
sumber
Coba ini :
Namun berdasarkan kinerja, praktik berikut ini lebih baik dan lebih dioptimalkan dalam penggunaan memori (ketika array kami berisi lebih banyak item seperti jutaan):
sumber
g.Key.PersonId
?g.SelectMany
?? Anda jelas tidak mencoba ini.SortedDictionary <PersonIdInt, SortedDictionary <CarNameString, CarInfoClass>>
. Yang paling dekat saya bisa menggunakan LINQ adalahIEnumerable <IGrouping <PersonIdInt, Dictionary <CarNameString, PersonIdCarNameXrefClass>>>
. Saya berakhir menggunakanfor
metode loop Anda yang, btw, 2x lebih cepat. Juga, saya akan menggunakan: a)foreach
vs.for
dan b)TryGetValue
vs.ContainsKey
(keduanya untuk prinsip KERING - dalam kode & runtime).Cara alternatif untuk melakukan ini dapat memilih
PersonId
grup berbeda dan bergabung denganpersons
:Atau sama dengan sintaks API yang lancar:
GroupJoin menghasilkan daftar entri dalam daftar pertama (daftar
PersonId
dalam kasus kami), masing-masing dengan sekelompok entri yang tergabung dalam daftar kedua (daftarpersons
).sumber
Contoh berikut menggunakan metode GroupBy untuk mengembalikan objek yang dikelompokkan berdasarkan
PersonID
.Atau
Atau
Atau Anda dapat menggunakan
ToLookup
, Pada dasarnyaToLookup
menggunakan.EqualityComparer<TKey>
Kesalahan untuk membandingkan kunci dan melakukan apa yang harus Anda lakukan secara manual saat menggunakan grup oleh dan ke kamus. Saya pikir itu dikecam di memorisumber
Pertama, setel bidang kunci Anda. Kemudian sertakan bidang Anda yang lain:
sumber