Fiona
Fiona

Reputation: 1221

Finding Difference Between Values in Two JavaScript Arrays of Objects

I have two JavaScript arrays which contain objects, like this:

var array1 = [{'123': '18'}, {'578': '2'}, {'323': '5'}];
var array2 = [{'123': '18'}, {'578': '1'}, {'323': '3'}];

Each array will have the same keys as the other (though perhaps not in the same order). However, the values may be different for a given key. What I want is an array of the objects in array2 that have different values for the same key in array1. So, for this example, I want:

[{'578': '1'}, {'323': '3'}]

What I have tried I've tried to do this with jQuery's .inArray() and .grep() methods, but these are handing me back every object, not just the ones with changed values:

difference = $.grep(array1,function(x) {
  return $.inArray(x, array2) < 0
})

Here is my fiddle. jQuery or regular JavaScript (or even Angular) solutions would be great. Thanks.

Upvotes: 2

Views: 137

Answers (7)

PPB
PPB

Reputation: 3087

using java-script JSBIN

var array1 = [ {'578': '2'}, {'323': '5'},{'123': '18'}];
var array2 = [{'123': '18'}, {'578': '1'}, {'323': '3'}];
var result = [];
for(var k in array2){
  var key = Object.keys(array2[k]).join();

  for(var l in array1){
  if(array1[l][key]){
    if(array1[l][key] != array2[k][key]){
     result.push(array2[k]);
    }
   }
  }
}
console.log(JSON.stringify(result));
//"[{\"578\":\"1\"},{\"323\":\"3\"}]"

Upvotes: 0

n-dru
n-dru

Reputation: 9430

Try this:

var array1 = [{'578': '2'}, {'123': '18'}, {'323': '5'}];
var array2 = [{'123': '18'}, {'578': '1'}, {'323': '3'}];
var removed = [];
for(var k in array2){
    var found = k;
    for(var x in array2){
        if(JSON.stringify(array2[k]) ==  JSON.stringify(array1[x])){
            found = true;
            break;
        }
    }
    if(found !== true){
        removed.push(array2[found]);
    }
}

array2 = removed;
console.log(array2);

Output:

[Object { 578="1"}, Object { 323="3"}]

https://jsfiddle.net/or44aguz/1/

Upvotes: 1

radcliff
radcliff

Reputation: 25

Following snippets works even if the order is changed.

var array1 = [{'123': '18'}, {'578': '2'}, {'323': '5'}];
var array2 = [{'123': '18'}, {'578': '1'}, {'323': '3'}];
var res=[];
for(var i=0;i<array2.length;i++){
var jsonObj=array2[i];
var j=0; var key;

for(var k in jsonObj){
if(j==0){
key=k;
j++;
}
}

var value=array2[i][key];
var flag=0;
for(var i2=0;i2<array1.length;i2++){
if(array1[i2][key]==value) flag=1;
}
if(flag==0)res.push(array2[i])

}
console.log(res);

Finally print res.

Upvotes: 0

fuyushimoya
fuyushimoya

Reputation: 9813

Create a stupid code, but order dosen't matters.

var array1 = [{'123': '18'}, {'578': '2'}, {'323': '5'}];
var array2 = [{'123': '18'}, {'578': '1'}, {'323': '3'}];
var array3 = [{'578': '1'}, {'323': '3'}, {'123': '18'}];

function getDiff(array1, array2) {
    var map = {};
    var result = [];

    var l = array1.length;
    var i, obj, key;

    for (i = 0; i < l; ++i) {
        obj = array1[i];
        key = JSON.stringify(obj);
        map[key] = true;
    }
    
    var compare;
    for (i = 0; i < l; ++i) {
        obj = array2[i];
        key = JSON.stringify(obj);
        if (map[key] !== true) {
          result.push(obj);
        }
    }
    return result;
}

console.log(getDiff(array1, array2));
console.log(getDiff(array1, array3));

Upvotes: 0

ttzn
ttzn

Reputation: 2613

First, you need to merge the "key-value" objects into one to enable direct lookup of keys, regardless of the order.

var argList = [{}].concat(array2);
// lookup will contain all key-value pairs in array2
var lookup = $.extend.apply($, argList);

Then, traverse array1 and use the keys to lookup the corresponding values in array2 and collect differences in the results array :

var results = [];
$.each(array1, function(index, element) {
    for (var k in element) {
        if (element[k] != lookup[k])
            results.push({ k : lookup[k] });
    }
});

Upvotes: 1

briosheje
briosheje

Reputation: 7446

Just some fun with filter:

var array1 = [{'123': '18'}, {'578': '2'}, {'323': '5'}];
var array2 = [{'123': '18'}, {'578': '1'}, {'323': '3'}];

difference = array1.filter(function(el, index) {
   return JSON.stringify(el) !== JSON.stringify(array2[index]);
});

console.log(difference);

Which is really the same as looping one array and checking the other, but you won't have indexes and so on, just more compact.

Just a side note: You can't directly compare objects because === operator checks if they yield the same memory location, so the cleanest and fastest solution is to convert them to strings (using JSON.stringify) and check if they are really the same thing afterall.

fiddle http://jsfiddle.net/pac2ps9t/1/

Upvotes: 0

Roland Szabo
Roland Szabo

Reputation: 153

The reason, why your method fails is, that javascript compares arrays and objects by comparing references. For example

var a = ['a','b','c'];
var b = ['a','b','c'];
a === b; // false

I suggest you, to check this answers:

Upvotes: 0

Related Questions