Menggabungkan ide dari Christoph dan mengasumsikan beberapa metode iterasi non-standar pada array dan objek / hash ( eachdan teman-teman), kita bisa mendapatkan perbedaan yang ditetapkan, penyatuan dan persimpangan dalam waktu linier dalam total sekitar 20 baris:
var setOPs = {
minusAB : function (a, b) {
var h = {};
b.each(function (v) { h[v] = true; });
return a.filter(function (v) { return !h.hasOwnProperty(v); });
},
unionAB : function (a, b) {
var h = {}, f = function (v) { h[v] = true; };
a.each(f);
b.each(f);
return myUtils.keys(h);
},
intersectAB : function (a, b) {
var h = {};
a.each(function (v) { h[v] = 1; });
b.each(function (v) { h[v] = (h[v] || 0) + 1; });
var fnSel = function (v, count) { return count > 1; };
var fnVal = function (v, c) { return v; };
return myUtils.select(h, fnSel, fnVal);
}
};
Ini mengasumsikan bahwa eachdan filterditentukan untuk array, dan kami memiliki dua metode utilitas:
myUtils.keys(hash): mengembalikan array dengan kunci hash
myUtils.select(hash, fnSelector,
fnEvaluator): mengembalikan larik dengan hasil pemanggilan fnEvaluator
pasangan kunci / nilai yang
fnSelectormengembalikan nilai true.
Ini select()secara longgar terinspirasi oleh Common Lisp, dan hanya filter()dan map()digulung menjadi satu. (Akan lebih baik untuk menetapkannya Object.prototype, tetapi melakukannya akan merusak jQuery, jadi saya memilih metode utilitas statis.)
Kinerja: Menguji dengan
var a = [], b = [];
for (var i = 100000; i--; ) {
if (i % 2 !== 0) a.push(i);
if (i % 3 !== 0) b.push(i);
}
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.