Reputation: 159
How to write an equivalent simple Javascript method for '_.intersectionWith' method of LodashJs library
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.intersectionWith(objects, others, _.isEqual);
Output: [{ 'x': 1, 'y': 2 }]
I wanted it work on array of strings as well. Is there any way to do it without O(n^2) iterations ?
Appreciate your help.
Upvotes: 2
Views: 992
Reputation: 33496
Here's a highly functional, plain-JS implementation of _.intersectionWith
:
var objects = [{'x':1,'y':2},{'x':2,'y':1}],
others = [{'x':1,'y':1},{'x':1,'y':2}];
function isEqual(a, b) {
return JSON.stringify(a) === JSON.stringify(b);
}
function intersectionWith(firstArray) {
var otherArrays = Array.prototype.slice.call(arguments, 1, -1),
comparator = arguments[arguments.length - 1];
return firstArray.filter(function(a) {
return otherArrays.every(function(arr) {
return arr.some(function(b) {
return comparator(a, b);
});
});
});
}
console.log(intersectionWith(objects, others, isEqual));
In ES6, this can be even shorter if you allow the comparator to be the first parameter.
function intersectionWith() {
var [comp, first, ...others] = [...arguments];
return first.filter(a => others.every(arr => arr.some(b => comp(a, b))));
}
Upvotes: 1
Reputation: 1465
UnderscoreJS 's annotated source has a rather vanilla implementation for intersection:
http://underscorejs.org/docs/underscore.html#section-62
_.intersection = function(array) {
var result = [];
var argsLength = arguments.length;
for (var i = 0, length = getLength(array); i < length; i++) {
var item = array[i];
if (_.contains(result, item)) continue;
for (var j = 1; j < argsLength; j++) {
if (!_.contains(arguments[j], item)) break;
}
if (j === argsLength) result.push(item);
}
return result;
};
The only dependencies, _.contains
and getLength
are pretty trivial as well.
Upvotes: 0