Сравнение значений двух объектов с вложенными циклами for
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);
Я пытаюсь сравнить 2 объекта по их значениям, используя вложенные циклы for. Возможно, это не лучший метод для такого простого сравнения, но, как новый стартер, я действительно хотел бы знать, почему он не работает должным образом.
1 ответ
В вашем коде есть некоторые ошибки. Прежде всего, вы сравниваете i
с j
, когда вы действительно хотите сравнить некоторые значения.
Я бы решил проблему, взяв ключи объекта и итерируя между ними. Если оба объекта имеют эти ключи И значения одинаковы, я добавлю их в эквивалентный массив.
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 работает здесь или здесь.
В этом случае общее рекурсивное решение может работать так, как показано ниже:
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
поле, так как они равны (в моем примере). Наличие значений true/false в массиве среди cat
Строка может сбивать с толку, поэтому вы можете добавить имя ключа вместо значения для полей bool.
Вы можете изменить if и push следующим образом:
if (typeof Obj1[k] === 'boolean') {
equivalent.push(`(${k}, ${Obj1[k]})`);
} else {
equivalent.push(Obj1[k]);
}
Это даст следующий результат:
[
"cat",
"(football, true)"
]
Дайте знать, если у вас появятся вопросы. Ура!