首页
学习
活动
专区
圈层
工具
发布

比较
EN

Stack Overflow用户
提问于 2014-08-22 21:49:32
回答 9查看 47.2K关注 0票数 34

问题(来自雄辩的Javascript第2版,第4章,练习4):

编写一个函数deepEqual,它接受两个值,只有当它们是相同值或具有相同属性的对象时才返回true,与递归调用deepEqual相比,这些对象的值也是相等的。

测试用例:

代码语言:javascript
复制
var obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
// → true
console.log(deepEqual(obj, {here: 1, object: 2}));
// → false
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
// → true

我的代码:

代码语言:javascript
复制
var deepEqual = function (x, y) {
  if ((typeof x == "object" && x != null) && (typeof y == "object" && y != null)) {
    if (Object.keys(x).length != Object.keys(y).length)
      return false;
    for (var prop in x) {
      if (y.hasOwnProperty(prop))
        return deepEqual(x[prop], y[prop]);
    /*This is most likely where my error is. The question states that all the values
    should be checked via recursion; however, with the current setup, only the first
    set of properties will be checked. It passes the test cases, but I would like
    to solve the problem correctly!*/
      }
    }
  else if (x !== y)
    return false;
  else
    return true;
}

我想我已经有了大致的想法;但是,正如我在评论中所说的,程序将不会检查对象中的第二个属性。我觉得自己有一个结构/逻辑问题,只是以错误的方式使用递归,因为我最初打算循环这些属性,使用递归来比较第一个属性的值,然后继续循环到下一个属性,然后再进行比较。不过,我不确定这是否可能?

我考虑了很多,尝试了几种不同的方法,但这是我到目前为止得出的最正确的答案。有什么建议可以指引我走向正确的方向吗?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2014-08-22 21:59:44

正如你所怀疑的,你正在返回第一次看到的属性的匹配。如果该属性不匹配,则应返回false,但请继续查找其他属性。

此外,如果在false上没有找到prop属性,则返回y (即计数匹配,但不符合实际属性)。

如果所有属性都匹配,则返回true

代码语言:javascript
复制
var deepEqual = function (x, y) {
  if (x === y) {
    return true;
  }
  else if ((typeof x == "object" && x != null) && (typeof y == "object" && y != null)) {
    if (Object.keys(x).length != Object.keys(y).length)
      return false;

    for (var prop in x) {
      if (y.hasOwnProperty(prop))
      {  
        if (! deepEqual(x[prop], y[prop]))
          return false;
      }
      else
        return false;
    }
    
    return true;
  }
  else 
    return false;
}

代码语言:javascript
复制
var deepEqual = function (x, y) {
  if (x === y) {
    return true;
  }
  else if ((typeof x == "object" && x != null) && (typeof y == "object" && y != null)) {
    if (Object.keys(x).length != Object.keys(y).length)
      return false;

    for (var prop in x) {
      if (y.hasOwnProperty(prop))
      {  
        if (! deepEqual(x[prop], y[prop]))
          return false;
      }
      else
        return false;
    }

    return true;
  }
  else 
    return false;
}

var obj = {here: {is: "an", other: "3"}, object: 2};
console.log(deepEqual(obj, obj));
// → true
console.log(deepEqual(obj, {here: 1, object: 2}));
// → false
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
// → false
console.log(deepEqual(obj, {here: {is: "an", other: "2"}, object: 2}));
// → false
console.log(deepEqual(obj, {here: {is: "an", other: "3"}, object: 2}));
// → true

票数 51
EN

Stack Overflow用户

发布于 2017-08-14 21:14:48

觉得这个版本更易读(更容易理解)。不过,这一逻辑与上面的答案非常相似。(ES6这次)

代码语言:javascript
复制
function deepEqual(obj1, obj2) {

    if(obj1 === obj2) // it's just the same object. No need to compare.
        return true;

    if(isPrimitive(obj1) && isPrimitive(obj2)) // compare primitives
        return obj1 === obj2;

    if(Object.keys(obj1).length !== Object.keys(obj2).length)
        return false;

    // compare objects with same number of keys
    for(let key in obj1)
    {
        if(!(key in obj2)) return false; //other object doesn't have this prop
        if(!deepEqual(obj1[key], obj2[key])) return false;
    }

    return true;
}

//check if value is primitive
function isPrimitive(obj)
{
    return (obj !== Object(obj));
}

顺便说一句,有一个欺骗版本的深度相等,它的工作像一个魅力),然而,它大约是1.6倍的速度。

,正如zero298注意到的,这种方法对属性排序很敏感,不应该被认真对待

代码语言:javascript
复制
function cheatDeepEqual(obj1, obj2)
{
    return JSON.stringify(obj1) === JSON.stringify(obj2);
}
票数 17
EN

Stack Overflow用户

发布于 2014-08-22 21:59:21

您可以在for循环之外使用一个变量来跟踪比较:

代码语言:javascript
复制
var allPropertiesEqual = true;
for (var prop in x) {
    if (y.hasOwnProperty(prop)) {
        allPropertiesEqual = deepEqual(x[prop], y[prop]) && allPropertiesEqual;
    } else {
        allPropertiesEqual = false;
    }
}
return allPropertiesEqual;

前面的示例不是故意优化的。因为您正在比较对象,您知道只要找到一个不等式就可以return false,并且可以在前面检查的所有属性相等的情况下继续循环:

代码语言:javascript
复制
for (var prop in x) {
    if (y.hasOwnProperty(prop)) {
        if (! deepEqual(x[prop], y[prop]) )
            return false; //first inequality found, return false
    } else {
        return false; //different properties, so inequality, so return false
    }
}
return true;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25456013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档