Membiarkan A
dan B
menjadi dua set. Saya mencari cara yang sangat cepat atau elegan untuk menghitung perbedaan set ( A - B
atau A \B
, tergantung pada preferensi Anda) di antara keduanya. Kedua set disimpan dan dimanipulasi sebagai array Javascript, seperti judulnya.
Catatan:
- Trik khusus tokek tidak masalah
- Saya lebih suka tetap menggunakan fungsi asli (tetapi saya terbuka untuk perpustakaan ringan jika jauh lebih cepat)
- Saya telah melihat, tetapi belum diuji, JS.Set (lihat poin sebelumnya)
Edit: Saya melihat komentar tentang set yang mengandung elemen duplikat. Ketika saya mengatakan "set", saya mengacu pada definisi matematika, yang berarti (antara lain) tidak mengandung elemen duplikat.
javascript
arrays
set-difference
Matt Ball
sumber
sumber
indexOf
implementasi yang lambat .Jawaban:
jika tidak tahu apakah ini paling efektif, tapi mungkin yang terpendek
Diperbarui ke ES6:
sumber
!B.includes(x)
sebagai penggantiB.indexOf(x) < 0
:)Nah, 7 tahun kemudian, dengan objek Set ES6 itu cukup mudah (tetapi masih tidak sekompak python
A - B
), dan dilaporkan lebih cepat daripadaindexOf
array besar:sumber
Anda dapat menggunakan objek sebagai peta untuk menghindari pemindaian linier
B
untuk setiap elemenA
seperti dalam jawaban pengguna187291 :The non-standar
toSource()
metode yang digunakan untuk mendapatkan nama properti yang unik; jika semua elemen sudah memiliki representasi string unik (seperti halnya angka), Anda dapat mempercepat kode dengan menghilangkantoSource()
pemanggilan.sumber
Yang terpendek, menggunakan jQuery, adalah:
sumber
not
tidak lagi berfungsi dengan objek umum mulai 3.0.0-rc1. Lihat github.com/jquery/jquery/issues/3147Saya akan melakukan hash pada array B, lalu menyimpan nilai dari array A yang tidak ada di B:
sumber
getDifference(a, b, hashOfB)
jika tidak lulus akan dihitung jika tidak digunakan kembali sebagaimana adanya.Menggabungkan ide dari Christoph dan mengasumsikan beberapa metode iterasi non-standar pada array dan objek / hash (
each
dan teman-teman), kita bisa mendapatkan perbedaan yang ditetapkan, penyatuan dan persimpangan dalam waktu linier dalam total sekitar 20 baris:Ini mengasumsikan bahwa
each
danfilter
ditentukan untuk array, dan kami memiliki dua metode utilitas:myUtils.keys(hash)
: mengembalikan array dengan kunci hashmyUtils.select(hash, fnSelector, fnEvaluator)
: mengembalikan larik dengan hasil pemanggilanfnEvaluator
pasangan kunci / nilai yangfnSelector
mengembalikan nilai true.Ini
select()
secara longgar terinspirasi oleh Common Lisp, dan hanyafilter()
danmap()
digulung menjadi satu. (Akan lebih baik untuk menetapkannyaObject.prototype
, tetapi melakukannya akan merusak jQuery, jadi saya memilih metode utilitas statis.)Kinerja: Menguji dengan
memberikan dua set dengan 50.000 dan 66.666 elemen. Dengan nilai-nilai ini AB membutuhkan waktu sekitar 75ms, sedangkan union dan intersection masing-masing sekitar 150ms. (Mac Safari 4.0, menggunakan Javascript Date untuk pengaturan waktu.)
Saya pikir itu hasil yang layak untuk 20 baris kode.
sumber
hasOwnProperty()
meskipun elemennya numerik: jika tidak, sesuatu sepertiObject.prototype[42] = true;
sarana42
tidak akan pernah terjadi dalam set hasilMenggunakan Underscore.js (Perpustakaan untuk JS fungsional)
sumber
Beberapa fungsi sederhana, meminjam dari jawaban @ milan:
Pemakaian:
sumber
Adapun cara berpuasa, ini tidak begitu elegan tetapi saya telah menjalankan beberapa tes untuk memastikannya. Memuat satu larik sebagai objek jauh lebih cepat untuk diproses dalam jumlah besar:
Hasil:
Namun, ini hanya berfungsi dengan string . Jika Anda berencana untuk membandingkan set bernomor, Anda akan ingin memetakan hasil dengan parseFloat .
sumber
b.filter(function(v) { return !A[v]; });
dalam fungsi kedua?Ini berfungsi, tetapi saya pikir yang lain jauh lebih pendek, dan juga elegan
sumber