13

我有两个JavaScript数组orig(对象的原始数组)和update(更新的对象的orig数组),它们具有相同的长度并包含对象,并且我想输出每对对象之间的差异。如何找到两个JavaScript对象数组之间的差异?

例子:

var orig = [{enabled:"true", name:"Obj1", id:3},{enabled:"true", name:"Obj2", id:4}]; 

var update = [{enabled:"true", name:"Obj1", id:3}, {enabled:"true", name:"Obj2-updated", id:4}]; 

输出应该是:name:"Obj2-updated"

我实现的东西,但它需要优化......

for(var prop=0; prop<orig.length; prop++) { 
    for(prop=0; prop<update.length; prop++) { 
    if(orig[prop].enabled != update.enabled) { console.log(update.enabled) } 
    if(orig[prop].name != update[prop].name) { console.log(update[prop].name) } 
    if(orig[prop].id != update[prop].id) { console.log(update[prop].id) } 
    } 
} 
+0

是输出一个字符串还是一个对象?或者包含对象或字符串的数组,或者? –

+0

虽然我不知道你的用例,但我只有一个已更改值的列表,而不知道哪个键和哪个对象的变化值存在,你确定你不需要更多的细节?我并不是想贬低你的问题,但是我试图预测你的下一个问题可能是什么,如果你错了只需要改变的价值。 –

+0

我只是需要输出创建一个字符串文本,说:“嘿,你改变Obj2 Obj2更新”。但我只需要知道哪个属性被修改了。 – Valip

回答

12

你可以过滤键和获取与更新的密钥的结果集。

var orig = [{ enabled: "true", name: "Obj1", id: 3 }, { enabled: "true", name: "Obj2", id: 4 }], 
 
    update = [{ enabled: "true", name: "Obj1", id: 3 }, { enabled: "true", name: "Obj2-updated", id: 4 }], 
 
    difference = []; 
 

 
orig.forEach(function (a, i) { 
 
    Object.keys(a).forEach(function (k) { 
 
     if (a[k] !== update[i][k]) { 
 
      difference.push({ id: update[i].id, key: k, value: update[i][k], index: i }); 
 
     } 
 
    }); 
 
}); 
 

 
console.log(difference);

+0

你能请告诉我是否有方法记录修改后的对象?在这种情况下,{{enabled:“true”,name:“Obj2-updated”,id:4}' – Valip

+7

你明白了,这就是为什么[如果你确信你只需要改变的值](http://stackoverflow.com/questions/39074429/how-to-find-differences-between-two-javascript-arrays-of-objects#comment65497981_39074429)。到目前为止,问题已经发生了变化,并且所需的返回值已经从已更改的值更改为已更改值*和*该值的关键字,现在*您已决定要整个修改要返回的对象。请在提出问题之前花五分钟*来正确地撰写问题。 –

+1

@PavelValeriu,如果我知道,**结果应该如何,我可以给出答案。所以你需要什么?该对象,或索引或键/值对或什么? –

6

假设,这两个属性名称相同并且这些值只是基元(无对象,数组等):

Object.keys(orig) 
     .forEach((key) => { 
     if(orig[ key ] !== update[ key ]) { 
      console.log(update[key]); 
     } 
     }); 
+0

我可以使用'orig [prop] [key]'吗? – Valip

+0

@PavelValeriu要做什么?在你的示例代码中,你假设两个变量都包含数组,但实际上它们是对象。所以你的'。长度“实际上不应该工作(除非你明确地设置它) – Sirko

+0

这是不值得我发布一个单独的答案,因为它本质上是相同的,但由于OP只想知道哪些值是不同的(不参考键,显然)使用['Object.values()'](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/values)更容易一些,而不是访问值通过每次迭代时的键(这确实需要在浏览器中实现'Object.values()',但显然)。 –

3

使用Object.keys来循环你的对象。喜欢的东西:

var orig = { 
 
    enabled: "true", 
 
    name: "Obj1", 
 
    id: 3 
 
}; 
 

 
var update = { 
 
    enabled: "true", 
 
    name: "Obj1-updated", 
 
    id: 3 
 
}; 
 

 
var diff = {}; 
 

 
Object.keys(orig).forEach(function(key) { 
 
    if (orig[key] != update[key]) { 
 
    diff[key] = update[key]; 
 
    }; 
 
}) 
 

 
console.log(diff);

3

您可以使用一个循环来遍历原始对象的属性和核对更新的对象,找出哪些属性已被修改。

var orig = { 
 
    enabled: "true", 
 
    name: "Obj1", 
 
    id: 3 
 
}; 
 

 
var update = { 
 
    enabled: "true", 
 
    name: "Obj1-updated", 
 
    id: 3 
 
}; 
 

 
for (var key in orig) { 
 
    if (orig[key] !== update[key]) { 
 
    console.log(key + ': ' + update[key]); 
 
    } 
 
}

0

你可以使用一个像库或lodash Ramda做以简明的方式。在拉达的情况下你可以这样做: R.difference(update, orig);

相关问题