Marz Marz - 5 months ago 36
Javascript Question

How do I find the intersection of an array of arrays that contain objects using Javascript/underscorejs?

I can't figure out how to find the intersection of this set of arrays:

[
[
{"name":"product1","light":"1"},
{"name":"product2","light":"2"},
{"name":"product5","light":"5"},
{"name":"product4","light":"4"}
],
[
{"name":"product2","light":"2"},
{"name":"product3","light":"3"},
{"name":"product4","light":"4"}
],[...more arrays with objects]
]


This is just sample data, the real set I have changes a lot but with that structure. I want the returned intersection to look like this (a single array of the intersected objects):

[
{"name":"product2","light":"2"},
{"name":"product4","light":"4"},
]


I tried this together with LoDashjs and Underscorejs:

_.intersectionObjects = _.intersect = function(array) {
var slice = Array.prototype.slice; // added this line as a utility
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
//return _.indexOf(other, item) >= 0;
return _.any(other, function(element) { return _.isEqual(element, item); });
});
});
};


I need this because I am trying to create a tags system using knockoutjs. I have a layout of categorized tag buttons that write to a "filter" observable array on click, the only thing left is to find the intersection of the filtered products that are contained in this observable array.

Please help me out, I've been trying to solve this for two days straight but lack the javascript knowledge to figure it out. Thanks in advance!

Answer

try adding they apply method:

  var myArr = [
    [
      {"name":"product1","light":"1"},
      {"name":"product2","light":"2"},
      {"name":"product5","light":"5"},
      {"name":"product4","light":"4"}
    ],
    [
      {"name":"product2","light":"2"},
      {"name":"product3","light":"3"},
      {"name":"product4","light":"4"}
    ]
  ]

  _.intersectionObjects = _.intersect = function(array) {
    var slice = Array.prototype.slice;
    var rest = slice.call(arguments, 1);
    return _.filter(_.uniq(array), function(item) {
      return _.every(rest, function(other) {
        return _.any(other, function(element) {
          return _.isEqual(element, item);
        });
      });
    });
  };

  var myIntersection = _.intersectionObjects.apply(_, myArr);

  for (var i = 0; i < myIntersection.length; i++) {
    console.log(myIntersection[i]);
  }

  // Sample Output:
  // Object {name: "product2", light: "2"}
  // Object {name: "product4", light: "4"}
Comments