/** @summary 集合演算を提供する */
var SetOp = ( function () {
"use strict";
var _compare = function ( a, b ) {
return a === b ? 0 : a < b ? -1 : 1;
},
_base = function ( operator ) {
var a = [],
b = [],
i = 0,
j = 0,
result = [],
operation = {
intersection: {
equal: function () {
result.push( a[ i ] );
},
lesser: function () {},
greater: function () {},
result: function () {
return result;
}
},
difference: {
equal: function () {},
lesser: function () {
result.push( a[ i ] );
},
greater: function () {},
result: function () {
return result.concat( a.slice( i ) );
}
},
union: {
equal: function () {
result.push( a[ i ] );
},
lesser: function () {
result.push( a[ i ] );
},
greater: function () {
result.push( b[ j ] );
},
result: function () {
return result.concat( a.slice( i ) );
}
}
}[ operator ];
return function ( operandA, operandB, compare ) {
compare = compare || _compare;
a = [].concat( operandA ).sort( compare );
b = [].concat( operandB ).sort( compare );
while ( a[ i ] && b[ j ] ) {
switch ( compare( a[ i ], b[ j ] ) ) {
case 0:
operation.equal();
i += 1;
j += 1;
break;
case -1:
operation.lesser();
i += 1;
break;
case 1:
operation.greater();
j += 1;
break;
}
}
return operation.result();
};
};
return {
/** @summary 共通部分を求める
* @param {Array} operandA 被演算子 A
* @param {Array} operandB 被演算子 B
* @param {Function} compare カスタム比較関数
* @returns {Array} 演算結果(共通部分)
*/
intersection: _base( "intersection" ),
/** @summary 差集合を求める
* @param {Array} operandA 被演算子 A
* @param {Array} operandB 被演算子 B
* @param {Function} compare カスタム比較関数
* @returns {Array} 演算結果(差集合)
*/
difference: _base( "difference" ),
/** @summary 和集合を求める
* @param {Array} operandA 被演算子 A
* @param {Array} operandB 被演算子 B
* @param {Function} compare カスタム比較関数
* @returns {Array} 演算結果(和集合)
*/
union: _base( "union" )
};
}() );