Skip to content

Instantly share code, notes, and snippets.

@dhenson02
Last active June 12, 2016 23:04
Show Gist options
  • Save dhenson02/85e93a9d7ab51e7237d461fd8c0df301 to your computer and use it in GitHub Desktop.
Save dhenson02/85e93a9d7ab51e7237d461fd8c0df301 to your computer and use it in GitHub Desktop.

Revisions

  1. dhenson02 revised this gist Jun 12, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion deepDiff.js
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@
    * @returns <Array>(Object*)
    */

    deepDiff: function deepDiff ( item1, item2, isReversed ) {
    function deepDiff ( item1, item2, isReversed ) {

    function isEmpty ( val ) {
    return typeof val === 'undefined' || val === null || Number.isNaN(val);
  2. dhenson02 created this gist Jun 11, 2016.
    123 changes: 123 additions & 0 deletions deepDiff.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,123 @@
    /**
    * Custom deep diffing to tell what changes throughout our data transfers
    * Don't recommend for testing functions or recursively-nested objects (like Backbone collections).
    * @param item1 <>
    * @param item2 <>
    * @param [isReversed] <Boolean>
    * @returns <Array>(Object*)
    */

    deepDiff: function deepDiff ( item1, item2, isReversed ) {

    function isEmpty ( val ) {
    return typeof val === 'undefined' || val === null || Number.isNaN(val);
    }

    function makeFail ( val1, val2, key ) {
    return {
    key: key,
    val1: !isReversed ? val1 : val2,
    val2: !isReversed ? val2 : val1
    };
    }

    function propDiff ( first, second, key ) {
    if ( isEmpty(first) || isEmpty(second) ) {
    return [ makeFail(first, second, key) ]
    }
    var firstKeys = Object.keys(first);
    var secondKeys = Object.keys(second);

    var needsReverse = firstKeys.length !== secondKeys.length;

    var fails = Object.keys(first).reduce(function ( fails, key ) {
    // console.log(key, first[ key ], second[ key ]);
    if ( first[ key ] === second[ key ] ) {
    return fails;
    }
    if ( !second.hasOwnProperty(key) ) {
    needsReverse = true;
    fails.push(makeFail(first[ key ], '***MISSING***', key));
    }
    else {
    return fails.concat(compareValues(first[ key ], second[ key ], key));
    }
    return fails;
    }, []);

    if ( needsReverse === true && isReversed !== true ) {
    return fails.concat(deepDiff(second, first, true));
    }
    return fails;
    }

    function testArrays ( val1, val2, key, isReversed ) {

    var shouldContinue = function ( val1, val2 ) {
    return typeof val1 === typeof val2 && (
    typeof val1 !== 'string' ||
    typeof val1 !== 'number' ||
    typeof val1 !== 'boolean' );
    };

    var needsReverse = val1.length !== val2.length;

    var fails = val1.reduce(function ( missing, value, index ) {
    var newKey = key !== null ?
    ( key + '[' + index + ']' ) :
    index;

    if ( val2.indexOf(value) === -1 ) {
    if ( shouldContinue(value, val2[ index ]) ) {
    return missing.concat(deepDiff(value, val2[ index ], newKey));
    }
    else {
    needsReverse = true;
    missing.push(makeFail(value, '***MISSING***', newKey));
    }
    }
    return missing;
    }, []);
    if ( needsReverse === true && isReversed !== true ) {
    return fails.concat(testArrays(val2, val1, key, true));
    }
    return fails;
    }

    function compareValues ( val1, val2, key ) {
    var fails = [];
    if ( typeof val1 === 'object' ) {
    if ( typeof val2 === 'object' ) {
    if ( Array.isArray(val1) ) {
    if ( Array.isArray(val2) ) {
    return fails.concat(testArrays(val1, val2, key));
    }
    else {
    fails.push(makeFail(val1, val2, key));
    }
    }
    else {
    return fails.concat(propDiff(val1, val2, key));
    }
    }
    else {
    fails.push(makeFail(val1, val2, key));
    }
    }
    else {
    fails.push(makeFail(val1, val2, key));
    }
    return fails;
    }

    function diff ( first, second ) {
    return first !== second ? compareValues(first, second, null) : [];
    }

    if ( typeof item2 === 'undefined' ) {
    return function ( item2 ) {
    return diff(item1, item2);
    }
    }
    return diff(item1, item2);
    }