Adakah ide tentang cara memeriksa apakah daftar itu adalah subset dari yang lain?
Secara khusus, saya punya
List<double> t1 = new List<double> { 1, 3, 5 };
List<double> t2 = new List<double> { 1, 5 };
Bagaimana memeriksa bahwa t2 adalah himpunan bagian dari t1, menggunakan LINQ?
Jawaban:
sumber
Gunakan HashSet sebagai ganti List jika bekerja dengan set. Maka Anda cukup menggunakan IsSubsetOf ()
Maaf itu tidak menggunakan LINQ. :-(
Jika Anda perlu menggunakan daftar, maka solusi @ Jared bekerja dengan peringatan bahwa Anda perlu menghapus elemen berulang yang ada.
sumber
Jika Anda menguji unit, Anda juga dapat menggunakan metode CollectionAssert.IsSubsetOf :
Dalam kasus di atas ini berarti:
sumber
Ini adalah solusi yang jauh lebih efisien daripada yang diposkan di sini, terutama solusi teratas:
Jika Anda dapat menemukan elemen tunggal di t2 yang tidak ada di t1, maka Anda tahu bahwa t2 bukan subset dari t1. Keuntungan dari metode ini adalah bahwa hal itu dilakukan semua di tempat, tanpa mengalokasikan ruang tambahan, tidak seperti solusi yang menggunakan .Except atau .Intersect. Lebih jauh lagi, solusi ini dapat pecah segera setelah menemukan satu elemen yang melanggar kondisi subset, sementara yang lain terus mencari. Di bawah ini adalah bentuk panjang optimal dari solusi, yang hanya sedikit lebih cepat dalam pengujian saya daripada solusi singkat di atas.
Saya melakukan beberapa analisis kinerja yang belum sempurna dari semua solusi, dan hasilnya sangat drastis. Kedua solusi ini sekitar 100x lebih cepat daripada .Except () dan .Intersect (), dan tidak menggunakan memori tambahan.
sumber
!t2.Except(t1).Any()
sedang dilakukan. Linq bekerja kembali ke sebagainya.Any()
bertanyaIEnumerable
apakah ada setidaknya satu elemen. Dalam skenariot2.Except(t1)
ini hanya memancarkan elemen pertamat2
yang tidak ada dalamt1
. Jika elemen pertamat2
tidak ada dit1
dalamnya selesai tercepat, jika semua element2
dit1
dalamnya berjalan paling lama.t1={1,2,3,...9999}
dant2={9999,9998,99997...9000}
, Anda mendapatkan pengukuran berikut:!t2.Except(t1).Any(): 1ms -> t2.All(e => t1.Contains(e)): 702ms
. Dan semakin buruk rentang semakin besar.t2.Except (t1)
mengembalikanIEnumerable
bukanCollection
. Ini hanya memancarkan semua item yang mungkin jika Anda beralih sepenuhnya di atasnya, misalnya denganToArray ()
atauToList ()
atau digunakanforeach
tanpa merusak di dalamnya. Cari eksekusi linq yang ditangguhkan untuk membaca lebih lanjut tentang konsep itu.t2={1,2,3,4,5,6,7,8}
t1={2,4,6,8}
t2.Except(t1)
=> elemen pertama t2 = 1 => perbedaan 1 ke t1 adalah 1 (diperiksa terhadap {2,4,6,8}) =>Except()
memancarkan elemen pertama 1 =>Any()
mendapat elemen =>Any()
menghasilkan true => tidak ada pemeriksaan elemen lebih lanjut di t2.@ Solusi Cameron sebagai metode ekstensi:
Pemakaian:
(Ini mirip, tetapi tidak persis sama dengan yang diposting di blog @ Michael)
sumber
Membangun jawaban dari @Cameron dan @Neil saya menulis metode ekstensi yang menggunakan terminologi yang sama dengan kelas Enumerable.
sumber
misalnya:
sumber
Coba ini
Idenya di sini adalah bahwa Intersect hanya akan mengembalikan nilai-nilai yang ada di kedua Array. Pada titik ini jika panjang himpunan yang dihasilkan sama dengan himpunan asli, maka semua elemen dalam "himpunan" juga dalam "centang" dan karenanya "himpunan" adalah himpunan bagian dari "toCheck"
Catatan: Solusi saya tidak berfungsi jika "set" memiliki duplikat. Saya tidak mengubahnya karena saya tidak ingin mencuri suara orang lain.
Petunjuk: Saya memilih jawaban Cameron.
sumber