用深度比较或json.stringify比较两个对象?

时间:2017-09-19 13:45:53

标签: javascript angularjs lodash

我有一个复杂的JSON对象,我想比较如下:

$scope.new = [
  {
    "name": "Node-1",
    "isParent": true,
    "text" : [
       {
           "str" : "This is my first Node-1 string",
           "parent":[]
       },
       {
          "str" : "This is my second Node-1 string",
           "parent":[]
       }],
     "nodes": [
      {
        "name": "Node-1-1",
        "isParent": false,
         "text" : [
           {
             "str" : "This is my first Node-1-1 string",
             "parent":[]
           },
           {
             "str" : "This is my second Node-1-1 string",
             "parent":[]
           }],
           "nodes": [
           {
            "name": "Node-1-1-1",
            "isParent": false,
            "text" : [
            {
              "str" : "This is my first Node-1-1-1 string",
              "parent":[]
            },
            {
              "str" : "This is my second Node-1-1-1 string",
              "parent":[]
            }],
            "nodes": []
          }
        ]
      }
    ]
  }
]

但是在比较时我想忽略1个属性,但是当我使用Angular.js时,我没有看到angular.equal中的任何选项,它会在比较2个对象时省略该属性。

 console.log(angular.equals($scope.new,$scope.copy)); 

因此,在进行研究时,我带来了以下答案,这是使用lodash有发射选项,但问题是我想省略创建一个副本,我想我会在lodash的情况下性能下降。

Exclude some properties in comparison using isEqual() of lodash

所以现在我正在考虑将对象转换为字符串,然后进行比较,我想这会很快但问题是如何在字符串比较时省略该属性?

这样的事情:

var str1 = JSON.stringify(JSON.stringify($scope.new));

var str2 = JSON.stringify(JSON.stringify($scope.copy));

console.log(str1==str2);

注意:我想在比较2个对象时忽略isParent属性。

比较2对象的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

在这些情况下,转换为字符串不是最好的方法。 将它们保留为对象。

使用loadash:

const propertiesToExclude = ['isParent'];
let result = _.isEqual(
  _.omit(obj1, propertiesToExclude),
  _.omit(obj2, propertiesToExclude)
);

使用普通的AngularJS,创建删除不需要的属性的对象的副本,然后比较它们:

let firstObj = angular.copy(obj1);
let secondObj = angular.copy(obj2);
const propertiesToExclude = ['isParent'];
function removeNotComparatedProperties(obj) {
  propertiesToExclude.forEach(prop => {
    delete obj[prop];
  });
}

removeNotComparatedProperties(firstObj);
removeNotComparatedProperties(secondObj);
angular.equals(firstObj, secondObj);

答案 1 :(得分:1)

如果使用_.isEqualWith,您可以使用lodash并覆盖用于深度比较的标准比较器:

var objA = {
  isParent: true,
  foo: {
    isParent: false,
    bar: "foobar"
  }
};

var objB = {
  isParent: false,
  foo: {
    isParent: true,
    bar: "foobar"
  }
};

var comparator = function(left, right, key) {
  if (key === 'isParent') return true; // if the key is 'isParent', mark the values equal
  else return undefined;               // else fall back to the default behavior
}

var isEqual = _.isEqualWith(objA, objB, comparator);

console.log(isEqual); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

排除多个属性,请相应地扩展比较器功能:

var comparator = function(left, right, key) {
  if (key === 'isParent' || key === 'anotherKey') return true;
  else return undefined;
}

你也可以在语法上使用许多不同的方法,这取决于你喜欢什么 - 一个switch语句,一个你迭代的数组......