【问题标题】:Compare 2 arrays of objects with Underscore to find the differnce将 2 个对象数组与下划线进行比较以找出差异
【发布时间】:2020-11-13 01:44:35
【问题描述】:

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

原件:

[
{"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"}
]

新:

[
{"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"}
]

如果我更改新的评级之一,我如何检测到该更改并检索更改的对象?

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

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

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

}, true); 

谢谢, 斯蒂芬

【问题讨论】:

  • 这些是数组中的相同对象(即===身份)还是只是看起来相似?
  • 你需要什么结果?更改对象在数组中的索引,新更改对象,旧更改对象,评分?
  • 我更喜欢更改后的对象,即 {"ListingId":1762276,"Rating":2,"ListPrice":7411828,"PropertyType":"Residential"}

标签: javascript underscore.js


【解决方案1】:

看看这个:

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

代码基于下划线的原始函数difference,但它使用isEqual在对象之间进行深度比较。

【讨论】:

  • 太棒了,它的作用。我希望我能理解代码。
【解决方案2】:

如果顺序没有改变,一个简单的迭代就可以了。下划线为此任务提供find method

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

【讨论】:

    【解决方案3】:

    怎么样:

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

    【讨论】:

      【解决方案4】:

      基于@Jonathan 的回答,我调整了一个版本,该版本返回一个可用的差异列表,包括哪一方有差异和记录的索引。

      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":1832131,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"},
      {"ListingId":1829932,"Rating":4,"ListPrice":750000,"PropertyType":"Residential"},
      {"ListingId":1827548,"Rating":5,"ListPrice":650000,"PropertyType":"Residential"}
      ]
      
      function diff(arr1, arr2){
          var aDiffs=[]
          function __comp(arrL, arrR, side){
              var rL, rR, bFound
              for(var i=0;i<arrL.length;i++){rL=arrL[i]
                  bFound=false
                  for(var j=0;j<arrR.length;j++){rR=arrR[j]
                      if (_.isEqual(rL, rR)){ 
                          bFound=true
                          break
                      }
                  }
                  if (!bFound)aDiffs.push({side: side, ind: i, obj: rL})
              }
          }
          __comp(arr1, arr2, 'l')
          __comp(arr2, arr1, 'r')
          return aDiffs
      };
      
      
      console.log(JSON.stringify(diff(b, a)).replace(/},{/g, "}\n,{"));
      

      输出:

      [{"side":"l","ind":0,"obj":{"ListingId":1762276,"Rating":2,"ListPrice":7411828,"PropertyType":"Residential"}}
      ,{"side":"l","ind":3,"obj":{"ListingId":1832131,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"}}
      ,{"side":"r","ind":0,"obj":{"ListingId":1762276,"Rating":3,"ListPrice":7411828,"PropertyType":"Residential"}}
      ,{"side":"r","ind":3,"obj":{"ListingId":1832134,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"}}]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-27
        • 2020-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多