比较2个对象的值和嵌套的for循环

时间:2019-01-26 22:35:28

标签: javascript javascript-objects object-comparison

var has = {
    name: 'dog',
    surname: 'cat',
    skills : {
        football: true,
        basketball: true,
        volleyball: true
    }
}

var pas = {
    name: 'dolphin',
    surname: 'cat',
    skills : {
        football: false,
        basketball: false,
        volleyball: true
    }
}

function compare(Obj1, Obj2) {
    var values1 = Object.values(Obj1);
    var values2 = Object.values(Obj2);
    var equivalent = [];
    for (var i = 0; i < values1.length; i++) {
        for (var j = 0; j < values2.length; j++) {
            if (i === j ) {
                equivalent.push(values1[i]);
            } 
        }
    }
    console.log(equivalent, values1, values2);

}

compare(has, pas);

我正在尝试使用嵌套的for循环按值比较2个对象。进行这种简单比较可能不是最好的方法,但是作为一个新手,我真的很想知道为什么它不能正常工作。

1 个答案:

答案 0 :(得分:0)

您的代码中有一些错误。首先,当您实际要比较某些值时,您正在将ij进行比较。

我将通过获取对象的键并在它们之间进行迭代来解决该问题。如果两个对象都具有这些键并且值相同,则将它们添加到等效数组中。

var has = {
  name: 'dog',
  surname: 'cat',
  skills: {
    football: true,
  }
}

var pas = {
  name: 'dolphin',
  surname: 'cat',
  skills: {
    football: true,
  }
}

function compare(Obj1, Obj2) {
  var values1 = Object.values(Obj1);
  var values2 = Object.values(Obj2);
  var equivalent = [];

  var keys = Object.keys(Obj1);
  keys.forEach(k => {
    if (Obj1.hasOwnProperty(k) && Obj2.hasOwnProperty(k)) {
      if (Obj1[k] === Obj2[k]) {
        equivalent.push(Obj1[k]);
      }
    }
  });

  console.log(equivalent);
}

compare(has, pas);

但是,这不适用于嵌套对象,就像您的情况一样。为什么?因为即使嵌套的对象(在您的情况下为技能)具有相同的值,但它们是不同的对象,不同的引用,所以比较将失败。了解js中的对象比较如何工作herehere

在这种情况下,一般的递归解决方案可能会如下所示:

var has = {
  name: 'dog',
  surname: 'cat',
  skills: {
    football: true,
    basketball: true,
    volleyball: true
  }
}

var pas = {
  name: 'dolphin',
  surname: 'cat',
  skills: {
    football: true,
    basketball: false,
    volleyball: false
  }
}

function compare(Obj1, Obj2) {
  var values1 = Object.values(Obj1);
  var values2 = Object.values(Obj2);
  var equivalent = [];

  var keys = Object.keys(Obj1);
  keys.forEach(k => {
    if (Obj1.hasOwnProperty(k) && Obj2.hasOwnProperty(k)) {
      if (typeof Obj1[k] === 'object') {
        let recursiveAnswer = compare(Obj1[k], Obj2[k]);
        equivalent.push(...recursiveAnswer);
      } else if (Obj1[k] === Obj2[k]) {
        equivalent.push(Obj1[k]);
      }
    }
  });
  
  return equivalent;
}

let equiv = compare(has, pas);
console.log(equiv);

在这里,如果遇到也是对象的值,则会再次调用该函数。递归调用完成后,将推送部分答案。您将看到最终答案在此处还将包含true值,该值来自football字段,因为它们相等(在我的示例中)。在cat字符串中的数组中包含true / false值可能会造成混淆,因此您实际上可以添加键名而不是bool字段的值。

您可以这样修改if和push:

if (typeof Obj1[k] === 'boolean') {
    equivalent.push(`(${k}, ${Obj1[k]})`);
} else {
    equivalent.push(Obj1[k]);
}

这将产生以下输出:

[
  "cat",
  "(football, true)"
]

如果您有任何疑问,请告诉我。 干杯!