Apa yang tercepat (dan paling sedikit sumber daya intensif) untuk membandingkan dua besar (> 50.000 item) dan sebagai hasilnya memiliki dua daftar seperti yang di bawah ini:
- item yang muncul di daftar pertama tetapi tidak di yang kedua
- item yang muncul di daftar kedua tetapi tidak di yang pertama
Saat ini saya sedang bekerja dengan Daftar atau IReadOnlyCollection dan menyelesaikan masalah ini dalam permintaan LINQ:
var list1 = list.Where(i => !list2.Contains(i)).ToList();
var list2 = list2.Where(i => !list.Contains(i)).ToList();
Tapi ini tidak berkinerja sebaik yang saya inginkan. Adakah ide untuk membuat ini lebih cepat dan lebih sedikit sumber daya intensif karena saya perlu memproses banyak daftar?
Equals(object)
dan / atau mengimplementasikannyaIEquatable<T>
harus baik-baik saja.IEquatable<T>
implementasi atauobject.Equals(object)
metode. Sepertinya Anda harus membuat pertanyaan baru dengan contoh minimal yang dapat direproduksi - kami tidak dapat benar-benar mendiagnosis sesuatu dalam komentar.Lebih efisien akan menggunakan
Enumerable.Except
:Metode ini diimplementasikan dengan menggunakan eksekusi yang ditangguhkan. Itu artinya Anda bisa menulis misalnya:
Ini juga efisien karena secara internal menggunakan
Set<T>
untuk membandingkan objek. Ini bekerja dengan terlebih dahulu mengumpulkan semua nilai yang berbeda dari urutan kedua, dan kemudian streaming hasil yang pertama, memeriksa bahwa mereka belum pernah terlihat sebelumnya.sumber
Set<T>
dibangun dari urutan kedua (yaitu sepenuhnya iterated dan disimpan), maka item yang dapat ditambahkan dari urutan pertama dihasilkan.Where
ditangguhkan sebagian karenalist.Where(x => x.Id == 5)
nilai nomor5
disimpan di awal, bukan dieksekusi dengan malas.Ini berfungsi untuk semua tipe data primitif. Jika Anda perlu menggunakannya pada objek khusus yang perlu Anda terapkan
IEqualityComparer
Menentukan metode untuk mendukung perbandingan objek untuk kesetaraan.
sumber
SequenceEqual
sederhanabool
. OP menginginkan dua daftar hasil - dan menjelaskan apa yang mereka inginkan dalam hal operasi yang ditetapkan: "item yang muncul dalam daftar pertama tetapi tidak dalam yang kedua". Tidak ada indikasi bahwa pemesanan relevan, sedangkan SequenceEqual tidak mempertimbangkan untuk menjadi relevan. Tampaknya ini menjawab pertanyaan yang sama sekali berbeda.Jika Anda ingin hasil menjadi case-sensitive , yang berikut ini akan berfungsi:
firstNotSecond
akan mengandung b1.dllsecondNotFirst
akan mengandung b2.dllsumber
Bukan untuk Masalah ini, tapi di sini ada beberapa kode untuk membandingkan daftar yang sama dan tidak! benda identik:
sumber
Except
coba cara ini:
sumber
Terkadang Anda hanya perlu tahu apakah dua daftar itu berbeda, dan bukan apa perbedaannya. Dalam hal itu, pertimbangkan untuk menambahkan metode ekstensi ini ke proyek Anda. Perhatikan bahwa objek Anda yang terdaftar harus mengimplementasikan IEquatable!
Pemakaian:
Apa pun
Component
kelasnya, metode yang ditunjukkan di siniCar
harus diimplementasikan hampir secara identik.Sangat penting untuk mencatat bagaimana kami telah menulis GetHashCode. Untuk menerapkan dengan benar
IEquatable
,Equals
danGetHashCode
harus beroperasi pada properti instance dengan cara yang kompatibel secara logis.Dua daftar dengan konten yang sama masih objek yang berbeda, dan akan menghasilkan kode hash yang berbeda. Karena kita ingin kedua daftar ini diperlakukan sama, kita harus membiarkan
GetHashCode
menghasilkan nilai yang sama untuk masing-masingnya. Kita dapat melakukannya dengan mendelegasikan kode hash ke setiap elemen dalam daftar, dan menggunakan bitor XOR standar untuk menggabungkan semuanya. XOR adalah agnostik-urutan, jadi tidak masalah jika daftar diurutkan secara berbeda. Yang penting mereka hanya berisi anggota yang setara.Catatan: nama yang aneh adalah untuk menyiratkan fakta bahwa metode ini tidak mempertimbangkan urutan elemen dalam daftar. Jika Anda peduli dengan urutan elemen dalam daftar, metode ini bukan untuk Anda!
sumber
Saya telah menggunakan kode ini untuk membandingkan dua daftar yang memiliki jutaan catatan.
Metode ini tidak akan memakan banyak waktu
sumber
Jika hanya diperlukan hasil gabungan, ini juga akan berfungsi:
di mana T adalah jenis elemen daftar.
sumber
Mungkin ini lucu, tetapi bekerja untuk saya
string.Join ("", List1)! = string.Join ("", List2)
sumber
Saya pikir ini adalah cara sederhana dan mudah untuk membandingkan dua elemen daftar dengan elemen
sumber
Ini adalah solusi terbaik yang akan Anda temukan
sumber
List<T>
untuk setiap elemen dalamlist1
. Juga hasilnya dipanggillist3
ketika bukanList<T>
.