功能检查嵌套对象的“深平等”(Function checking for “deep equalit

2019-10-23 12:56发布

我想写来检查,如果两个物体具有相同的值的函数。 此功能要求我检查存储为原来的对象中值的所有对象的平等。 我已经制定(见下面的代码)的方法是首先检查非对象的值相等。 然后,如果所有这些比赛,我遍历对象再次做出了原有的功能,这让我比较的两个对象的每个嵌套层次递归调用。

但是,这种方法只是部分有效。 递归调用的性质意味着我只可以在第一密钥检查嵌套对象的平等 - 在对象值对。 我无法弄清楚如何检查,一旦第一组嵌套对象进行了对比含有嵌套对象的任何附加的键值对和递归调用返回。 下面是函数:

var deepEqual = function(val1, val2) {
  if (typeof val1 === 'object' && typeof val2 === 'object') {
      for (i in val1) {
        for (i in val2){
          if (typeof val1[i] !== 'object' && typeof val2[i] !== 'object') {
            if (val1[i] !== val2[i]) {
              return false
            }
          }
        }
      }
      for (i in val1) {
        for (i in val2){
          if (typeof val1[i] === 'object' && typeof val2[i] === 'object') {
            return deepEqual(val1[i], val2[i])
          }
        }
      }
    return true
  }
  else if (val1 === val2) {
    return true
  }
  else return false
}

我的基本问题是,我认为我需要一个递归调用检查嵌套对象的深平等,但我只能做这个检查一次成功。 有没有人试图解决这样的问题? 如果你需要更具体的,我会提供我的结果为特定对象的例子。 谢谢!

Answer 1:

一个简单的解决办法是JSON字符串化的对象和比较它们的字符串表示。 作为@Jan提到...

如果这个对象在完全相同的方式初始化只会工作。 如果性质是相同的,但在不同的顺序,它会失败

......这是一个有点脆,但可能满足您的要求。



Answer 2:

这里是一个可能的解决方案,但我建议你找到你自己的,真的。

function isEqual(var1, var2) { // Break the comparison out into a neat little function
  if (typeof var1 !== "object") {
    return var1===var2;
  } else {
    return deepEqual(var1, var2);
  }
}

function deepEqual(var1, var2) {
   for (i in var1) { 
      if(typeof var2[i] === "undefined") { // Quick check, does the property even exist?
         return false;
      }
      if (!isEqual(var1[i], var2[i])) {
         return false;
      }
   }
   return true;
}

function areObjectsEqual(obj1, obj2) {
   return deepEqual(obj1, obj2) && deepEqual(obj2, obj1); // Two-way checking
}

你不仅需要检查,如果一切都在obj1中存在obj2 ,而且在一切obj2中存在obj1 。 这种解决方案需要做的比较两种方式,但你可以极大地优化这一点。

而一些测试用例

var v1 = { obj0:"jan", obj:{ name:"jan"}, obj2:"ben" }
var v2 = { obj:{ name:"jan"}, obj2:"ben" }

console.log(areObjectsEqual(v1, v2))

v1 = { obj:{ name:"jan"}, obj2:"ben" }
v2 = { obj:{ name:"jan"}, obj2:"ben" }

console.log(areObjectsEqual(v1, v2))

v1 = { obj:{ name:"jan2"}, obj2:"ben" }
v2 = { obj:{ name:"jan"}, obj2:"ben" }

console.log(areObjectsEqual(v1, v2))

v1 = { obj:{ name:"jan"}, obj2:"ben" }
v2 = { obj:{ name:"jan"}, obj2:"ben", obj3:"pig" }

console.log(areObjectsEqual(v1, v2))


Answer 3:

你可能想要的是_.isEquallodashunderscore库。

也有deepEqual从测试Chai.js断言库。



文章来源: Function checking for “deep equality” of nested objects