javascript 将 2 个对象数组与 Underscore 进行比较以找出差异

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18383636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 11:42:30  来源:igfitidea点击:

Compare 2 arrays of objects with Underscore to find the differnce

javascriptunderscore.js

提问by Stephen Patten

I have 2 arrays, one is newVal and the other is origVal define

我有 2 个数组,一个是 newVal,另一个是 origVal 定义

orig:

来源:

[
{"ListingId":1762276,"Rating":3,"ListPrice":7411828,"PropertyType":"Residential"},
{"ListingId":1826692,"Rating":3,"ListPrice":650000,"PropertyType":"Residential"},
{"ListingId":1833283,"Rating":4,"ListPrice":950000,"PropertyType":"Residential"},
{"ListingId":1832134,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"},
{"ListingId":1829932,"Rating":4,"ListPrice":750000,"PropertyType":"Residential"},
{"ListingId":1827548,"Rating":5,"ListPrice":650000,"PropertyType":"Residential"}
]

new:

新的:

[
{"ListingId":1762276,"Rating":2,"ListPrice":7411828,"PropertyType":"Residential"},
{"ListingId":1826692,"Rating":3,"ListPrice":650000,"PropertyType":"Residential"},
{"ListingId":1833283,"Rating":4,"ListPrice":950000,"PropertyType":"Residential"},
{"ListingId":1832134,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"},
{"ListingId":1829932,"Rating":4,"ListPrice":750000,"PropertyType":"Residential"},
{"ListingId":1827548,"Rating":5,"ListPrice":650000,"PropertyType":"Residential"}
]

If I change one of the ratings in new, how might I detect that change, and retrieve the changed object?

如果我在 new 中更改其中一个评级,我如何检测该更改并检索更改的对象?

There will only be one change at a time, although I don't think that matters.

一次只会有一个变化,虽然我认为这并不重要。

FYI: These arrays are being produced from an Anjularjs watchcollection

仅供参考:这些数组是从 Anjularjs watchcollection 生成的

$scope.$watchCollection('items', function (new, old) {

}, true); 

Thank you, Stephen

谢谢你,斯蒂芬

回答by Jonathan Naguin

Take a look to this:

看看这个:

var a = [
{"ListingId":1762276,"Rating":3,"ListPrice":7411828,"PropertyType":"Residential"},
{"ListingId":1826692,"Rating":3,"ListPrice":650000,"PropertyType":"Residential"},
{"ListingId":1833283,"Rating":4,"ListPrice":950000,"PropertyType":"Residential"},
{"ListingId":1832134,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"},
{"ListingId":1829932,"Rating":4,"ListPrice":750000,"PropertyType":"Residential"},
{"ListingId":1827548,"Rating":5,"ListPrice":650000,"PropertyType":"Residential"}
];

var b = [
{"ListingId":1762276,"Rating":2,"ListPrice":7411828,"PropertyType":"Residential"},
{"ListingId":1826692,"Rating":3,"ListPrice":650000,"PropertyType":"Residential"},
{"ListingId":1833283,"Rating":4,"ListPrice":950000,"PropertyType":"Residential"},
{"ListingId":1832134,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"},
{"ListingId":1829932,"Rating":4,"ListPrice":750000,"PropertyType":"Residential"},
{"ListingId":1827548,"Rating":5,"ListPrice":650000,"PropertyType":"Residential"}
]

var difference = function(array){
   var rest = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));

   var containsEquals = function(obj, target) {
    if (obj == null) return false;
    return _.any(obj, function(value) {
      return _.isEqual(value, target);
    });
  };

  return _.filter(array, function(value){ return ! containsEquals(rest, value); });
};

console.log(JSON.stringify(difference(b, a)));
> [{"ListingId":1762276,"Rating":2,"ListPrice":7411828,"PropertyType":"Residential"}]

The code is based on the original function differencefrom underscore, but it performs a deep comparison between objects using isEqual.

该代码基于与 underscore的原始函数差异,但它使用isEqual执行对象之间的深度比较。

回答by Bergi

If the order does not change, a simple iteration will do it. Underscore provides the findmethodfor this task:

如果顺序不变,一个简单的迭代就可以了。Underscore为这个任务提供了find方法

var changedObj = _.find(newVal, function(obj, index) {
    return obj.Rating != oldVal[index].Rating;
});

回答by thecommoner

How about:

怎么样:

const current = [{name:'a'},{name:'b'},{name:'c'}]
const update = [{name:'x'},{name:'a'},{name:'b'},{name:'f'}]
const records = current.concat(update);
const diff = {};
diff.in = []
diff.out = [];
records.forEach(item => {
  if(!current.find(cur => item.name == cur.name))diff.in.push(item)
  if(!update.find(up => item.name == up.name ))diff.out.push(item)
})