Last active
January 4, 2017 18:50
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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