Не работает один из созданных методов создания объектов
Есть два функции, первая работающая, вторая нет, как можно исправить вторую, чтобы с помощью двойных циклов был тот же результат?
Первая:
function deepEqual1(a, b) {
if (a === b) return true;
if (a == null || typeof a != "object" ||
b == null || typeof b != "object") return false;
let keysA = Object.keys(a), keysB = Object.keys(b);
if (keysA.length != keysB.length) return false;
for (let key of keysA) {
if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
}
return true;
}
Вторая:
function deepEqual2(obj1, obj2) {
if (typeof(obj1) === typeof(obj2) === 'object' !== null) {
for (let i in obj1) {
for (let c in obj2) {
let len = Object.keys(obj1);
if (obj1[i] == obj2[c]) {
//console.log(obj1[i])
console.log(i)
}
}
}
}
}
let 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
Ответы (1 шт):
Автор решения: OPTIMUS PRIME
→ Ссылка
Бросилось в глаза (интерпретируется слева направо, не работает как ожидалось):
► typeof(obj1) === typeof(obj2) === 'object' !== null
//typeof(obj1) === typeof(obj2) → true
► true === 'object' !== null
//true === 'object' → false
► false !== null
true
По функции: Рекурсия сама вместо вас в процессе хранит необходимые данные. Если хочется делать это без рекурсии, придется во время цикла «руками» их где-то хранить и вытаскивать.
let 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
console.log(deepEqual({a:{b:{c:{d:{e:{f:1}}}}}}, {a:{b:{c:{d:{e:{f:1}}}}}})); // true
function deepEqual(a, b) {
if (a === b) return true;
if (a == null || typeof a != "object" ||
b == null || typeof b != "object") return false;
/***/
// Сначала будет перебирать все ключи начального объекта.
// Если будет натыкаться на вложенные объекты - добавит их в очередь проверок.
let queue = [];
// Когда перебор первого уровня завершен - заглянет в очередь,
// и повторит итерацию дла вложенных в неё объектов.
let keys_a = Object.keys(a).sort(), keys_b = Object.keys(b).sort();
if (keys_a.length != keys_b.length) return false;
let curr_a = a, curr_b = b;
let i = 0;
while (true) {
let key_a = keys_a[i], key_b = keys_b[i];
i++;
if (key_a !== key_b) return false;
let val_a = curr_a[key_a], val_b = curr_b[key_b];
if (val_a !== val_b) {
if (val_a !== null && typeof val_a == "object" &&
val_b !== null && typeof val_b == "object") {
queue.push([val_a, val_b]); // Объекты идут парами, в массиве.
continue;
} else {
// Значения не равны, и это не объекты.
return false;
}
}
/***/
if (i >= keys_a.length) {
// Перебор всех ключей объекта завершен.
if (queue.length == 0) {
// В очереди больше нет объектов - значит все оказались равны.
return true;
} else {
// Обновляет счетчик и "текущие" ключи для будущих итераций.
i = 0;
[curr_a, curr_b] = queue.pop();
keys_a = Object.keys(curr_a).sort(), keys_b = Object.keys(curr_b).sort();
if (keys_a.length != keys_b.length) return false;
}
}
} // End while
}
val_a !== null && typeof val_a == "object" — Проверка на null нужна, чтобы условие точно оставляло только объекты.
console.log( typeof null ); // "object"