Compare 2 arrays of objects with Underscore to fin

2020-02-10 06:13发布

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

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?

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

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

}, true); 

Thank you, Stephen

3条回答
何必那么认真
2楼-- · 2020-02-10 06:58

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

var changedObj = _.find(newVal, function(obj, index) {
    return obj.Rating != oldVal[index].Rating;
});
查看更多
唯我独甜
3楼-- · 2020-02-10 07:00

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 difference from underscore, but it performs a deep comparison between objects using isEqual.

查看更多
家丑人穷心不美
4楼-- · 2020-02-10 07:00

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)
})
查看更多
登录 后发表回答