I'm working my way through the 3rd edition of Eloquent JavaScript and although I've seen one or two various answers on SO that seem almost identical in execution logic to mine that work mine just doesnt seem to no matter how I tweek it.
THE GOAL: create a deep parison function that can pare two objects and determine based on their properties if theyre different instances of the same type of object (same keys and values) regardless of reference...
Can anyone spot the bug in my code?
function deepEqual(a,b){
if((typeof a=='object'&& a!=null)&&(typeof b=='object'&& b!=null)){
if(Object.keys(a).length != Object.keys(b).length){return false}
for(let key in a){
if(a[key]==b[key]){
if(!deepEqual(a[key],b[key])){return false}
}else{
return false
}
}
return true
}else if(a!==b){return false}
else{return true}
}
var obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
// → true (reads true currently)
console.log(deepEqual(obj, {here: 1, object: 2}));
// → false (reads false currently)
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
// → true (reads false currently)
I'm working my way through the 3rd edition of Eloquent JavaScript and although I've seen one or two various answers on SO that seem almost identical in execution logic to mine that work mine just doesnt seem to no matter how I tweek it.
THE GOAL: create a deep parison function that can pare two objects and determine based on their properties if theyre different instances of the same type of object (same keys and values) regardless of reference...
Can anyone spot the bug in my code?
function deepEqual(a,b){
if((typeof a=='object'&& a!=null)&&(typeof b=='object'&& b!=null)){
if(Object.keys(a).length != Object.keys(b).length){return false}
for(let key in a){
if(a[key]==b[key]){
if(!deepEqual(a[key],b[key])){return false}
}else{
return false
}
}
return true
}else if(a!==b){return false}
else{return true}
}
var obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
// → true (reads true currently)
console.log(deepEqual(obj, {here: 1, object: 2}));
// → false (reads false currently)
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
// → true (reads false currently)
Share
Improve this question
edited Sep 25, 2018 at 10:05
icedwater
4,9063 gold badges38 silver badges53 bronze badges
asked Feb 11, 2018 at 5:17
user16801user16801
551 silver badge6 bronze badges
3 Answers
Reset to default 5The bug was here:
if (a[key] == b[key])
if they're objects the condition may return false even if they're "equal".
function deepEqual(a, b) {
if (a && b && typeof a == 'object' && typeof b == 'object') {
if (Object.keys(a).length != Object.keys(b).length) return false;
for (var key in a) if (!deepEqual(a[key], b[key])) return false;
return true;
} else return a === b
}
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
Looks like you just need to tweak your for-loop logic to catch objects like so (using your own logic):
for(let key in a){
let aValue = a[key]
let bValue = b[key]
if (typeof aValue == 'object' && typeof bValue == 'object') {
// catches nested objects and recursively assesses deep equality
if(!deepEqual(aValue, bValue)) return false
}
else if (aValue !== bValue) {
// if the values are not objects, catches if they are not equal
return false
}
}
You can play with this, here: https://jsbin./wotapezuwo/edit?js,console
You can use below function to deep pare values
function deepCompare(a,b){
// shallow check
if (a === b) return true;
// determining types
const typeA = Object.prototype.toString.call(a);
const typeB = Object.prototype.toString.call(b);
// if types are not equal
if (typeA != typeB) return false;
// paring if object
if (typeA === '[object Object]') {
if (Object.keys(a) !== Object.keys(b)) return false;
for (let key in a)
if (!deepCompare(a[key], b[key])) return false;
return true;
}
// paring if array
else if (typeA === '[object Array]') {
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; i++)
if (!deepCompare(a[i], b[i])) return false;
return true;
}
// paring if map
else if (typeA === "[object Map]") {
if (a.keys().length !== b.keys().length) return false;
for (let key of a.keys())
if (!deepCompare(a.get(key), b.get(key))) return false;
return true;
}
// paring if sets
else if (typeA === '[object Set]') {
let x = [...a], y = [...b];
return deepCompare(x, y);
}
// null & undefined checks
else if (typeA === '[object Undefined]' || typeA === '[object Null]')
return true;
// nothing matched
return false;
}
let a=[1,'a',{x:[1,2,3], y: new Map([['a',1], ['b', new Set([1,2,3])]])}]
let b=[1,'a',{x:[1,2,3], y: new Map([['a',1], ['b', new Set([1,2,3])]])}]
console.log(deepCompare(a,b)) // true
let c=[1,'a',{x:[1,2,3], y: new Map([['a',1], ['b', new Set([1,2,3])]])}]
let d=[1,'a',{x:[1,2,3], y: new Map([['a',1], ['b', 2]])}]
console.log(deepCompare(c, d)) //false
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745548866a4632469.html
评论列表(0条)