A place to discuss questions, approaches and solutions to the exercises found in the Eloquent Javascript book.
Chapter 4: Deep comparison (of objects)
@zsolt-nagy
I came up with two solutions to the Deep comparison problem. The simplest solution simply stringifies the objects and then does a compare. The other solution follows the book’s guidelines and iterates through the objects recursively comparing the object keys and values.
Question: In researching this problem on the Internet, I came across extremely complex methods for deep comparing objects. Would there be any reason not to use the stringify approach for comparing objects? It seems the least complex and easiest to test. Just wondering what considerations I may be ignorant of.
Solution: stringify
function deepEqual(x, y) {
//unless the params are objects, return false
if( !(typeof x === 'object' && x !== null) ) {return false;}
if( !(typeof y === 'object' && y !== null) ) {return false;}
//if there is referential equality, return true
if( x === y ) {return true;}
//unless all the properties and property values match, return false
if(!( JSON.stringify(x) === JSON.stringify(y) ) ) {return false;}
else {
return true;
}
}
Solution: iterate and compare over the object key/values
function deepEqual(x, y) {
//unless the params are objects, return false
if( !(typeof x === 'object' && x !== null) ) {return false;}
if( !(typeof y === 'object' && y !== null) ) {return false;}
//if there is referential equality, return true
if ( x === y ) {return true;}
const keys1 = Object.keys(x);
const keys2 = Object.keys(y);
//unless the objects have the same number of keys and key names, return false
if ( !((keys1.length == keys2.length) && ( JSON.stringify(keys1) === JSON.stringify(keys2))) ) {return false;}
//unless the key values match, return false
for (let key of keys1) {
//if the key values are objects
if( (( typeof x[key] === 'object' && x[key] !== null ) &&
( typeof y[key] === 'object' && y[key] !== null )) ) {
//then unless recursive deepEqual on objects is true, return false
if ( !(deepEqual(x[key], y[key])) ) {return false;}
}
//otherwise, unless key values are equal, return false
else if( !(x[key] === y[key]) ) {return false;}
}
return true;
}
@zsolt-nagy
Nevermind! I see that both my functions fail in the case where the objects have identical properties and values, but in different order. The JSON.stringify will return false when the properties/values are the same but in different order.
Deep comparison is meant to be very complex with a lot of potential debugging and keeping track of all " own properties" of an object/array. It’s a good advanced interview exercise for mid-senior developers, but if it’s far too hard, focus on practical applications and exercises.