Christoph'un fikrini birleştirerek ve diziler ve nesneler / hash'ler ( each
ve arkadaşlar) üzerinde birkaç standart olmayan yineleme yöntemi varsayarak , toplamda yaklaşık 20 satırda doğrusal zamanda set farkı, birleşim ve kesişim elde edebiliriz:
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);
}
};
Bu varsayar each
ve filter
diziler için tanımlanan ve iki yardımcı program yöntemleri olduğunu:
myUtils.keys(hash)
: hash anahtarlarını içeren bir dizi döndürür
myUtils.select(hash, fnSelector,
fnEvaluator)
: true döndüren fnEvaluator
anahtar / değer çiftlerinde
arama sonuçlarını içeren bir dizi fnSelector
döndürür.
select()
Gevşek Common Lisp esinlenerek ve ise sadece filter()
vemap()
bir arada. (Bunları açıklamak daha iyi olurdu Object.prototype
, ancak bunu yapmak jQuery ile hasara yol açtı , bu yüzden statik yardımcı program yöntemlerine karar verdim.)
Performans: ile test etme
var a = [], b = [];
for (var i = 100000; i--; ) {
if (i % 2 !== 0) a.push(i);
if (i % 3 !== 0) b.push(i);
}
50.000 ve 66.666 elemanlı iki set verir. Bu değerlerle AB yaklaşık 75ms alırken, birleşim ve kesişme her biri yaklaşık 150ms'dir. (Zamanlama için Javascript Tarihini kullanan Mac Safari 4.0.)
Bence bu 20 satır kod için iyi bir kazanç.