src/set-core.js
function concatUnique(aItems, bItems, algebra) {
	var idTree = {};
	var aSet;
	// IE 9 and 10 don't have Set.
	if(typeof Set !== "undefined") {
		aSet = new Set();  // jshint ignore:line
	}

	aItems.forEach(function(item) {
		var keyNode = idTree;
		if(aSet) {
			aSet.add(item);
		}
		each(algebra.clauses.id, function(prop) {
			var propVal = getProp(item, prop);
			if(keyNode && typeof propVal !== "undefined") {
				keyNode = keyNode[propVal] = keyNode[propVal] || {};
			} else {
				keyNode = undefined;
			}
		});
	});

	return aItems.concat(bItems.filter(function(item) {
		var keyNode = idTree;
		if(aSet && aSet.has(item)) {
			return false;
		}
		// IE9/10 case
		if(!aSet && aItems.indexOf(item) > -1) {
			return false;
		}
		each(algebra.clauses.id, function(prop) {
			keyNode = keyNode && keyNode[getProp(item, prop)];
		});
		return keyNode === idTree || !keyNode;
	}));
}
function concatUnique(aItems, bItems, algebra) {
	var idTree = {};
	var aSet;
	// IE 9 and 10 don't have Set.
	if(typeof Set !== "undefined") {
		aSet = new Set();  // jshint ignore:line
	}

	aItems.forEach(function(item) {
		var keyNode = idTree;
		if(aSet) {
			aSet.add(item);
		}
		each(algebra.clauses.id, function(prop) {
			var propVal = getProp(item, prop);
			if(keyNode && typeof propVal !== "undefined") {
				keyNode = keyNode[propVal] = keyNode[propVal] || {};
			} else {
				keyNode = undefined;
			}
		});
	});

	return aItems.concat(bItems.filter(function(item) {
		var keyNode = idTree;
		if(aSet && aSet.has(item)) {
			return false;
		}
		// IE9/10 case
		if(!aSet && aItems.indexOf(item) > -1) {
			return false;
		}
		each(algebra.clauses.id, function(prop) {
			keyNode = keyNode && keyNode[getProp(item, prop)];
		});
		return keyNode === idTree || !keyNode;
	}));
}
function concatUnique ( aItems , bItems , algebra ) { var idTree = { } ; var aSet ; // IE 9 and 10 don't have Set. if ( typeof Set !== "undefined" ) { aSet = new Set ( ) ; // jshint ignore:line } aItems . forEach ( function ( item ) { var keyNode = idTree ; if ( aSet ) { aSet . add ( item ) ; } each ( algebra . clauses . id , function ( prop ) { var propVal = getProp ( item , prop ) ; if ( keyNode && typeof propVal !== "undefined" ) { keyNode = keyNode [ propVal ] = keyNode [ propVal ] || { } ; } else { keyNode = undefined ; } } ) ; } ) ; return aItems . concat ( bItems . filter ( function ( item ) { var keyNode = idTree ; if ( aSet && aSet . has ( item ) ) { return false ; } // IE9/10 case if ( ! aSet && aItems . indexOf ( item ) > - 1 ) { return false ; } each ( algebra . clauses . id , function ( prop ) { keyNode = keyNode && keyNode [ getProp ( item , prop ) ] ; } ) ; return keyNode === idTree || ! keyNode ; } ) ) ; }
concatUnique concat all items in bItems onto aItems that do not already exist in aItems. same-object and ID collisions are both looked at when deciding whether an item matches another.
concatUnique concat all items in bItems onto aItems that do not already exist in aItems . same - object and ID collisions are both looked at when deciding whether an item matches another .