Bagaimana Anda membandingkan dua set javascript? Saya mencoba menggunakan ==
dan ===
tetapi keduanya mengembalikan false.
a = new Set([1,2,3]);
b = new Set([1,3,2]);
a == b; //=> false
a === b; //=> false
Kedua himpunan ini ekuivalen, karena menurut definisi, himpunan tidak memiliki urutan (setidaknya biasanya tidak). Saya telah melihat dokumentasi untuk Set di MDN dan tidak menemukan apa pun yang berguna. Ada yang tahu bagaimana melakukan ini?
javascript
set
ecmascript-6
kode william
sumber
sumber
===
adalah untuk persamaan nilai, bukan persamaan objek.new Set([1,2,3]) != new Set([1,2,3])
. Hal ini membuat Javascript Set tidak berguna untuk set set karena superset akan berisi subset duplikat. Satu-satunya solusi yang muncul dalam pikiran adalah mengonversi semua himpunan bagian menjadi larik, mengurutkan setiap larik, lalu mengenkode setiap larik sebagai string (misalnya JSON).Jawaban:
Coba ini:
Pendekatan yang lebih fungsional adalah:
The
all
karya fungsi untuk semua objek iterable (misalnyaSet
danMap
).Jika
Array.from
lebih banyak didukung maka kita bisa mengimplementasikanall
fungsi sebagai:Semoga membantu.
sumber
has
menjadiisPartOf
atauisIn
atauelem
Anda juga dapat mencoba:
sumber
lodash menyediakan
_.isEqual()
, yang melakukan perbandingan mendalam. Ini sangat berguna jika Anda tidak ingin menulis sendiri. Pada lodash 4,_.isEqual()
membandingkan Set dengan benar.sumber
Jawaban lain akan bekerja dengan baik; ini alternatif lain.
Namun, ketahuilah bahwa ini tidak melakukan perbandingan kesetaraan yang dalam. Begitu
akan mengembalikan false. Jika dua set di atas dianggap sama, kita perlu mengulang melalui kedua set tersebut dengan melakukan perbandingan kualitas yang mendalam pada setiap elemen. Kami menetapkan adanya
deepEqual
rutinitas. Maka logikanya akan seperti ituApa fungsinya: untuk setiap anggota s1, cari anggota s2 yang sangat setara. Jika ditemukan, hapus agar tidak dapat digunakan lagi. Kedua himpunan tersebut sangat sama jika semua elemen di s1 ditemukan di s2, dan s2 habis. Belum dicoba.
Anda mungkin menemukan ini berguna: http://www.2ality.com/2015/01/es6-set-operations.html .
sumber
Tak satu pun dari solusi ini membawa "kembali" fungsionalitas yang diharapkan ke struktur data seperti kumpulan kumpulan. Dalam keadaannya saat ini, Javascript Set tidak berguna untuk tujuan ini karena superset akan berisi subset duplikat, yang secara keliru dianggap Javascript sebagai perbedaan. Satu-satunya solusi yang dapat saya pikirkan adalah mengubah setiap subset menjadi Array , mengurutkannya dan kemudian mengkodekannya sebagai String (misalnya JSON).
Larutan
Penggunaan dasar
Tes terakhir: set set
sumber
[...set1].sort().toString() === [...set2].sort().toString()
Alasan mengapa pendekatan Anda mengembalikan nilai salah adalah karena Anda membandingkan dua objek yang berbeda (meskipun keduanya memiliki konten yang sama), sehingga membandingkan dua objek yang berbeda (bukan referensi, tetapi objek) selalu menghasilkan kesalahan.
Pendekatan berikut menggabungkan dua set menjadi satu dan dengan bodohnya membandingkan ukurannya. Jika sama, berarti sama:
Terbalik : Sangat sederhana dan pendek. Tidak ada perpustakaan eksternal hanya vanilla JS
Kelemahan : Ini mungkin akan menjadi lebih lambat daripada hanya mengulang nilai dan Anda membutuhkan lebih banyak ruang.
sumber
Membandingkan dua objek dengan ==, ===
Saat menggunakan operator
==
or===
untuk membandingkan dua objek, Anda akan selalu mendapatkanfalse
kecuali objek tersebut mereferensikan objek yang sama . Sebagai contoh:Jika tidak, == sama dengan false meskipun objek tersebut berisi nilai yang sama:
Anda mungkin perlu mempertimbangkan perbandingan manual
Di ECMAScript 6, Anda dapat mengonversi set ke array sebelumnya sehingga Anda dapat melihat perbedaan di antara mereka:
CATATAN:
Array.from
adalah salah satu fitur ECMAScript 6 standar tetapi tidak didukung secara luas di browser modern. Periksa tabel kompatibilitas di sini: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Browser_compatibilitysumber
b
yang tidak termasuka
?b
tidak masuka
adalah dengan memeriksa apakaha.size === b.size
.a.size === b.size
Pertama-tama, buat hubungan pendek perbandingan elemen-elemen individu jika tidak perlu?has
operasi pada set dirancang untuk menjadi sangat efisien, tidak sepertiindexOf
operasi pada array. Oleh karena itu, masuk akal untuk mengubah fungsi filter Anda menjadireturn !b.has(i)
. Itu juga akan menghilangkan kebutuhan untuk mengubahnyab
menjadi sebuah array.Saya membuat polyfill cepat untuk Set.prototype.isEqual ()
Github Gist - Set.prototype.isEqual
sumber
Berdasarkan jawaban yang diterima, dengan asumsi dukungan
Array.from
, berikut adalah satu kalimat:sumber
eqSet = (a,b) => a.size === b.size && [...a].every(b.has.bind(b))
Jika kumpulan hanya berisi tipe data primitif atau objek di dalam kumpulan memiliki persamaan referensi, maka ada cara yang lebih sederhana
const isEqualSets = (set1, set2) => (set1.size === set2.size) && (set1.size === new Set([...set1, ...set2]).size);
sumber
Saya mengikuti pendekatan ini dalam tes:
sumber
a=[1,2,3]
danb=[1,2,3,4]
, maka dikatakan sama. Jadi saya rasa Anda perlu pemeriksaan tambahan sepertisetA.size === setB.size
Modifikasi yang sangat sedikit berdasarkan jawaban @Aadit M Shah:
Jika ada orang lain yang mengalami masalah seperti yang saya lakukan karena beberapa kekhasan dari babel terbaru, harus menambahkan persyaratan eksplisit di sini.
(Juga untuk jamak menurut saya
are
hanya sedikit lebih intuitif untuk dibaca dengan keras 🙃)sumber
1) Periksa apakah ukurannya sama. Jika tidak, maka mereka tidak sama.
2) ulangi setiap elem A dan periksa yang ada di B. Jika salah satu gagal kembali
unequal
3) Jika 2 kondisi di atas gagal berarti sama.
2) Metode 2
sumber
forEach
metode TIDAK akan membuat fungsi induk kembali.