VignesHKumaR
VignesHKumaR

Reputation: 159

Lodash JS - Simulate '_.intersectionWith' in plain vanilla Javascript?

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

Answers (2)

castletheperson
castletheperson

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

kazenorin
kazenorin

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

Related Questions