Christophのアイデアを組み込み、配列およびオブジェクト/ハッシュ(each
およびフレンド)でいくつかの非標準の反復メソッドを想定すると、合計約20行の線形時間で差、和集合、交差を設定できます。
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);
}
};
これは、each
およびfilter
が配列に対して定義されていること、および2つのユーティリティメソッドがあることを前提としています。
myUtils.keys(hash)
:ハッシュのキーを持つ配列を返します
myUtils.select(hash, fnSelector,
fnEvaluator)
:true fnEvaluator
をfnSelector
返すキーと値のペアを呼び出した結果の配列を
返します。
select()
緩くCommon Lispのに触発されて、単にさfilter()
とmap()
一つにロールバックされます。(それらをで定義することObject.prototype
をお勧めしますが、そうすることでjQueryで大混乱が発生するため、静的ユーティリティメソッドを使用しました。)
パフォーマンス:テスト
var a = [], b = [];
for (var i = 100000; i--; ) {
if (i % 2 !== 0) a.push(i);
if (i % 3 !== 0) b.push(i);
}
50,000要素と66,666要素の2つのセットを提供します。これらの値では、ABは約75msかかりますが、unionと交差はそれぞれ約150msです。(Mac Safari 4.0、タイミングにJavaScript日付を使用)
これは、20行のコードにとって適切な見返りだと思います。