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:
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 each
dan filter
ditentukan 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
fnSelector
mengembalikan 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.