Saya memiliki situasi berikut
class Person
{
string Name;
int Value;
int Change;
}
List<Person> list1;
List<Person> list2;
Saya perlu menggabungkan 2 daftar menjadi yang baru List<Person>
jika itu orang yang sama catatan menggabungkan akan memiliki nama itu, nilai orang di list2, perubahan akan menjadi nilai list2 - nilai list1. Perubahan adalah 0 jika tidak ada duplikat
Jawaban:
Ini dapat dengan mudah dilakukan dengan menggunakan metode ekstensi Linq Union. Sebagai contoh:
Ini akan mengembalikan Daftar tempat kedua daftar digabungkan dan dobel dihapus. Jika Anda tidak menentukan pembanding dalam metode ekstensi Union seperti dalam contoh saya, ini akan menggunakan metode Persamaan dan GetHashCode default di kelas Person Anda. Misalnya, jika Anda ingin membandingkan orang dengan membandingkan properti Nama mereka, Anda harus mengganti metode ini untuk melakukan perbandingan sendiri. Periksa contoh kode berikut untuk mencapai itu. Anda harus menambahkan kode ini ke kelas Person Anda.
Jika Anda tidak ingin mengatur metode Persamaan default kelas Person Anda untuk selalu menggunakan Nama untuk membandingkan dua objek, Anda juga dapat menulis kelas pembanding yang menggunakan antarmuka IEqualityComparer. Anda kemudian dapat memberikan pembanding ini sebagai parameter kedua dalam metode Union extension Linq. Informasi lebih lanjut tentang cara menulis metode pembanding seperti ini dapat ditemukan di http://msdn.microsoft.com/en-us/library/system.collections.iequalitycomparer.aspx
sumber
Union
denganIntersect
?Concat
yang tidak menggabungkan duplikatSaya perhatikan bahwa pertanyaan ini tidak ditandai sebagai dijawab setelah 2 tahun - saya pikir jawaban terdekat adalah Richards, tetapi dapat disederhanakan cukup banyak untuk ini:
Meskipun ini tidak akan kesalahan dalam kasus di mana Anda memiliki nama duplikat di setiap set.
Beberapa jawaban lain menyarankan menggunakan penyatuan - ini jelas bukan cara untuk pergi karena hanya akan memberi Anda daftar yang berbeda, tanpa melakukan penggabungan.
sumber
Kenapa kamu tidak pakai saja
Concat
?Concat adalah bagian dari LINQ dan lebih efisien daripada melakukan
AddRange()
dalam kasus Anda:
sumber
Actually, due to deferred execution, using Concat would likely be faster because it avoids object allocation - Concat doesn't copy anything, it just creates links between the lists so when enumerating and you reach the end of one it transparently takes you to the start of the next!
Ini adalah poin saya.Ini Linq
Ini adalah Normaly (AddRange)
Ini Normaly (Foreach)
Ini adalah Normaly (Foreach-Dublice)
sumber
Ada beberapa bagian untuk melakukan ini, dengan asumsi setiap daftar tidak mengandung duplikat, Nama adalah pengidentifikasi unik, dan tidak ada daftar yang dipesan.
Pertama buat metode penambahan append untuk mendapatkan satu daftar:
Dengan demikian bisa mendapatkan satu daftar:
Kemudian kelompokkan nama
Kemudian dapat memproses setiap kelompok dengan helper untuk memproses satu kelompok pada suatu waktu
Yang dapat diterapkan untuk setiap elemen
grouped
:(Peringatan: tidak diuji.)
sumber
Append
Duplikat Anda hampir persis sama dengan out-of-the-boxConcat
.Enumerable.Concat
dan dengan demikian mengimplementasikannya kembali.Anda memerlukan sesuatu seperti gabungan luar penuh. System.Linq.Enumerable tidak memiliki metode yang mengimplementasikan gabungan luar penuh, jadi kita harus melakukannya sendiri.
sumber
Apakah kode berikut berfungsi untuk masalah Anda? Saya telah menggunakan foreach dengan sedikit linq di dalam untuk melakukan menggabungkan daftar dan berasumsi bahwa orang sama jika nama mereka cocok, dan tampaknya untuk mencetak nilai yang diharapkan saat dijalankan. Resharper tidak menawarkan saran untuk mengubah foreach menjadi LINQ jadi ini mungkin sebaik itu akan melakukannya dengan cara ini.
sumber
sumber