Skip to content

Instantly share code, notes, and snippets.

@metame
Last active January 4, 2017 18:50

Revisions

  1. metame revised this gist Jan 4, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion deepEqual.js
    Original file line number Diff line number Diff line change
    @@ -77,7 +77,7 @@ function tryStringify(obj){
    return JSON.stringify(obj);
    } catch (e) {
    console.log("Error stringifying:");
    console.log(o1);
    console.log(obj);
    console.log(e);
    }
    }
  2. metame revised this gist Jan 4, 2017. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions deepEqual.js
    Original file line number Diff line number Diff line change
    @@ -11,6 +11,7 @@ function deepEqual(o1, 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;
  3. metame revised this gist Jan 4, 2017. No changes.
  4. metame created this gist Jan 4, 2017.
    82 changes: 82 additions & 0 deletions deepEqual.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    /**
    * 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 ){
    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(o1);
    console.log(e);
    }
    }