Skip to content

Instantly share code, notes, and snippets.

@metame
Last active January 4, 2017 18:50
Show Gist options
  • Save metame/88a8c89df9457fce3d05950a1a24cad4 to your computer and use it in GitHub Desktop.
Save metame/88a8c89df9457fce3d05950a1a24cad4 to your computer and use it in GitHub Desktop.
deepEqual - yes, there are other deepEqual fn's but this is built for debugging to log where they're not equal
/**
* takes 2 objects and compares each property recursively
* @param {Object} o1 - 1st object
* @param {Object} o2 - 2nd object
* @returns {boolean}
*/
function deepEqual(o1, o2){
const o1string = tryStringify(o1);
const o2string = tryStringify(o2);
if ( o1string === o2string ){ // catch the easy ones
return true;
} else if ( Object.keys(o1).length !== Object.keys(o2).length ){
console.log("objects have different number of props");
return false;
} else {
let equal = true;
for ( let key in o1 ){
if ( o1.hasOwnProperty(key) ){
equal = checkEqual(key, o1, o2);
if ( !equal ) { break; }
}
}
return equal;
}
}
// order DOES matter
const equalityFunctions = {
matchKeys(key, o1, o2){
return o1.hasOwnProperty(key) && o2.hasOwnProperty(key);
},
matchType(key, o1, o2){
return typeof o1[key] === typeof o2[key];
},
matchValueSimple(key, o1, o2){ // take care of numbers & strings & pointers/refs
console.log(typeof o1[key]);
return (typeof o1[key] !== "object") ? o1[key] === o2[key] : true;
},
bothArrays(key, o1, o2){
return Array.isArray(o1[key]) ? Array.isArray(o1[key]) && Array.isArray(o2[key]) : true;
},
matchArrays(key, o1, o2){
return Array.isArray(o1[key]) ? areArraysEqual(o1[key], o2[key]) : true;
},
matchObjects(key, o1, o2){
return (typeof o1[key] === "object" && !Array.isArray(o1[key])) ? deepEqual(o1[key], o2[key]) : true;
}
}
/**
* sort then check deep equal
* @param {*[]} a1 - an array
* @param {*[]} a2 - another array
* @returns {boolean}
*/
function areArraysEqual(a1, a2){
return deepEqual(a1.sort(), a2.sort());
}
function checkEqual(key, o1, o2){
return Object.values(equalityFunctions).every( fn => checkTrue(key, o1, o2, fn) );
}
function checkTrue(key, o1, o2, fn){
return fn(key, o1, o2) || notEqual(key, o1, o2, fn.name);
}
function notEqual(key, o1, o2, fnName){
console.log(`${key} not equal on ${fnName}`);
console.log(o1[key]);
console.log(o2[key]);
}
function tryStringify(obj){
try {
return JSON.stringify(obj);
} catch (e) {
console.log("Error stringifying:");
console.log(obj);
console.log(e);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment