简体   繁体   English

在两个 JavaScript 对象数组中查找值之间的差异

[英]Finding Difference Between Values in Two JavaScript Arrays of Objects

I have two JavaScript arrays which contain objects, like this:我有两个包含对象的 JavaScript 数组,如下所示:

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 .我想要的是array2中的对象数组,它们对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:我尝试过的我尝试使用 jQuery 的.inArray().grep()方法来做到这一点,但这些方法将每个对象都交还给我,而不仅仅是那些值发生变化的对象:

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. jQuery 或常规 JavaScript(甚至 Angular)解决方案会很棒。 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/ 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 :然后,遍历 array1 并使用键查找 array2 中的相应值并收集results数组中的差异:

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.您的方法失败的原因是,javascript 通过比较引用来比较数组和对象。 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.只是一个旁注:你不能直接比较对象,因为===运算符检查它们是否产生相同的内存位置,所以最干净和最快的解决方案是将它们转换为字符串(使用 JSON.stringify)并检查它们是否真的毕竟同样的事情。

fiddle http://jsfiddle.net/pac2ps9t/1/小提琴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.最后打印 res.

using java-script JSBIN使用java脚本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\"}]"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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