简体   繁体   中英

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.

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/

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] });
    }
});

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:

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));

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/

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.

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\"}]"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM