Haymak3r
Haymak3r

Reputation: 1411

Finding an array's objects that are not present in another array by property

I'm looking for a way to find any objects in one array that are not present in another array based upon that object's property. What's the best way to do this with jQuery or underscore?

Given the following example:

"array1":[
    {"testProperty":"A"}, 
    {"testProperty":"B"}, 
    {"testProperty":"C"}
]

"array2":[
    {"testProperty":"A", "User":"Smith"}, 
    {"testProperty":"B", "User":"Smith"}, 

]

I would want to return the third object from array1 whose testProperty is "C" since it's not present in array2.

I was able to find several examples of this issue here on stackoverflow, but not when needing to do so using properties from those objects.

Upvotes: 2

Views: 484

Answers (5)

Gruff Bunny
Gruff Bunny

Reputation: 27976

You could use underscore's reject and some to get what you want:

var result = _.reject(array1, item => _.some(array2, {testProperty: item.testProperty}));

If performance is a concern and testProperty is an unique key of the objects in array2 then you could create a hash using indexBy and check for the result using has:

var hash = _.indexBy(array2, 'testProperty');
var result = _.reject(array1, item => _.has(hash, item.testProperty));

Upvotes: 1

maioman
maioman

Reputation: 18764

here's a version in plain es6 js using filter and some method:

array1 = [
    {"testProperty":"A"}, 
    {"testProperty":"B"}, 
    {"testProperty":"C"}
];

array2 =[
    {"testProperty":"A", "User":"Smith"}, 
    {"testProperty":"B", "User":"Smith"}, 

]
  
 var r = array1.filter(x =>
    ! Object.keys(x).some(z =>
      array2.some(w =>
      Object.keys(w).some(y => y === z && w[y] === x[z])
    )));
    
    document.write(JSON.stringify(r))

Upvotes: 1

peregrine42
peregrine42

Reputation: 341

I'm not sure if this counts, but if you can use lodash instead of underscore, there is a nice function called differenceBy:

var _ = require("lodash");

var array1 = [
  {"testProperty":"A"},
  {"testProperty":"B"},
  {"testProperty":"C"}
]

var array2 = [
  {"testProperty":"A", "User":"Smith"},
  {"testProperty":"B", "User":"Smith"}
]

var result = _.differenceBy(array1, array2, function(item) {
  return item["testProperty"]
});

console.log(result);

Upvotes: 3

Nenad Vracar
Nenad Vracar

Reputation: 122077

You can use filter with map

var a = {'array1': [{"testProperty":"A"}, {"testProperty":"B"}, {"testProperty":"C"}], 'array2': [{"testProperty":"A", "User":"Smith"}, {"testProperty":"B", "User":"Smith"}]};

var result = a.array1.filter(function(e) {
  return a.array2.map(el => { return el.testProperty}).indexOf(e.testProperty) == -1;
});

console.log(result);

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386680

A proposal in plain Javascript with a hash table for look-up.

var data = { "array1": [{ "testProperty": "A" }, { "testProperty": "B" }, { "testProperty": "C" }], "array2": [{ "testProperty": "A", "User": "Smith" }, { "testProperty": "B", "User": "Smith" }, ] },
    result = data.array1.filter(function (a) {
        return !this[a.testProperty];
    }, data.array2.reduce(function (r, a) {
        r[a.testProperty] = true;
        return r;
    }, Object.create(null)));

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Upvotes: 2

Related Questions