0

I have two arrays:

var collectionA = [
    {'name': 'Brandon', 'age': '41'}
];
var collectionB = [
    {'name': 'Brandon', 'age': '41'},
    {'name': 'Tom', 'age': '25'},
    {'name': 'Jimmy', 'age': '36'},
    {'name': 'Brian', 'age': '36'}
];

How can I get create a third array that is basically the result of subtracting collectionA from collectionB? FYI: I'm using Underscore and Backbone in this project and would love to do this with one or the other.

The third array would look like this:

var collectionC = [
    {'name': 'Tom', 'age': '25'},
    {'name': 'Jimmy', 'age': '36'},
    {'name': 'Brian', 'age': '36'}
];
rafaelcastrocouto
  • 11,781
  • 3
  • 38
  • 63
Brandon Durham
  • 7,096
  • 13
  • 64
  • 101
  • 5
    Note: There is no JSON here at all, what you have is Javascript arrays with Javascript objects. JSON is a text format for representing objects. – Guffa Oct 20 '14 at 17:04
  • there's no such thing as a "json array". there's json strings which can have array encoded into them. but you don't work with json strings the way you want. You DECODE them to a native structure, e.g. a javascript array, then do whatever you want with those native structures. – Marc B Oct 20 '14 at 17:06
  • Well step 1 is to write a function (or find one in your framework) to do some sort of property-based object comparison. Two objects with matching properties are still two objects, so there has to be a comparator. Once you've got that, then it's basically the same as a similar problem with lists of simple strings or numbers instead of objects. – Pointy Oct 20 '14 at 17:07

2 Answers2

0

You could use _.filter along with _.some on the second collection:

_.filter(collectionB, function(x) { 
    return !_.some(collectionA, function(y) { 
        return y.name == x.name 
    }) 
});

Or equivalently using _.reject:

_.reject(collectionB, function(x) { 
    return _.some(collectionA, function(y) { 
        return y.name == x.name 
    }) 
});

This probably isn't the most efficient though -- if you have large collections you'd probably want something more optimized (ie, make a hash map first to speed up the inner lookup).

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
0

SOLUTION

var collectionA = [
    {'name': 'Brandon', 'age': '41'},
    {'name': 'Tom', 'age': '25'},
    {'name': 'Jimmy', 'age': '36'},
    {'name': 'Brian', 'age': '36'}
];
var collectionB = [
    {'name': 'Brandon', 'age': '41'}
];
var subtract = function(a, b){
  var r = {};
  for(var i in a){
    var ai = a[i];
    for(var j in b){
      var bj = b[j];
      if(ai.name != bj.name || ai.age != bj.age){
       r[i] = ai;
      }
    }
  }
  return r;
};

var c = subtract(collectionA,collectionB);
rafaelcastrocouto
  • 11,781
  • 3
  • 38
  • 63