function diff(orig, dest, options) {
        var result, key, obj, objEx, origObj, origObjEx, i, t;
        orig = listToObject(orig, options.key);
        dest = listToObject(dest, options.key);
        result = { added: [], removed: [], modified: [], unchanged: [] };
        for (key in dest.valids) {
            if (dest.valids.hasOwnProperty(key)) {
                obj = dest.valids[key];
                origObj = orig.valids[key];
                if (origObj === undefined) {
                    result.added.push(obj);
                } else {
                    // keep and exclude
                    keep(origObj, obj, options);
                    objEx = exclude(obj, options.exclude);
                    origObjEx = exclude(origObj, options.exclude);
                    // compare
                    if (deepEqual(objEx, origObjEx)) {
                        result.unchanged.push(obj);
                    } else {
                        result.modified.push(obj);
                    }
                    delete orig.valids[key];
                }
            }
        }
        for (key in orig.valids) {
            if (orig.valids.hasOwnProperty(key)) {
                result.removed.push(orig.valids[key]);
            }
        }
        // discarded object (without a key)
        if (orig.discarded.length) {
            result.discardedOrig = orig.discarded;
        }
        if (dest.discarded.length) {
            result.discardedDest = dest.discarded;
        }
        // for (i = 0; i < orig.discarded.length; i =+ 1) {
        //     t = orig.discarded[i];
        // }

        return result;
    }
/**
     * Compare two arrays of objects and return the added/removed/modified objects
     *
     * options:
     * - key: name of the key (mandatory)
     * - exclude: optional list of excluded key (not compared)
     * - keep: optional list of keys copied (before comparing) from orig to dest
     */
Compare two arrays of objects and return the added/removed/modified objects
options:
- key: name of the key (mandatory)
- exclude: optional list of excluded key (not compared)
- keep: optional list of keys copied (before comparing) from orig to dest
Compare two arrays of objects and return the added / removed / modified objects options : - key : name of the key ( mandatory ) - exclude : optional list of excluded key ( not compared ) - keep : optional list of keys copied ( before comparing ) from orig to dest
function diff(orig, dest, options) {
        var result, key, obj, objEx, origObj, origObjEx, i, t;
        orig = listToObject(orig, options.key);
        dest = listToObject(dest, options.key);
        result = { added: [], removed: [], modified: [], unchanged: [] };
        for (key in dest.valids) {
            if (dest.valids.hasOwnProperty(key)) {
                obj = dest.valids[key];
                origObj = orig.valids[key];
                if (origObj === undefined) {
                    result.added.push(obj);
                } else {
                    keep(origObj, obj, options);
                    objEx = exclude(obj, options.exclude);
                    origObjEx = exclude(origObj, options.exclude);
                    if (deepEqual(objEx, origObjEx)) {
                        result.unchanged.push(obj);
                    } else {
                        result.modified.push(obj);
                    }
                    delete orig.valids[key];
                }
            }
        }
        for (key in orig.valids) {
            if (orig.valids.hasOwnProperty(key)) {
                result.removed.push(orig.valids[key]);
            }
        }
        if (orig.discarded.length) {
            result.discardedOrig = orig.discarded;
        }
        if (dest.discarded.length) {
            result.discardedDest = dest.discarded;
        }
        return result;
    }
function diff ( orig , dest , options ) { var result , key , obj , objEx , origObj , origObjEx , i , t ; orig = listToObject ( orig , options . key ) ; dest = listToObject ( dest , options . key ) ; result = { added : [ ] , removed : [ ] , modified : [ ] , unchanged : [ ] } ; for ( key in dest . valids ) { if ( dest . valids . hasOwnProperty ( key ) ) { obj = dest . valids [ key ] ; origObj = orig . valids [ key ] ; if ( origObj === undefined ) { result . added . push ( obj ) ; } else { keep ( origObj , obj , options ) ; objEx = exclude ( obj , options . exclude ) ; origObjEx = exclude ( origObj , options . exclude ) ; if ( deepEqual ( objEx , origObjEx ) ) { result . unchanged . push ( obj ) ; } else { result . modified . push ( obj ) ; } delete orig . valids [ key ] ; } } } for ( key in orig . valids ) { if ( orig . valids . hasOwnProperty ( key ) ) { result . removed . push ( orig . valids [ key ] ) ; } } if ( orig . discarded . length ) { result . discardedOrig = orig . discarded ; } if ( dest . discarded . length ) { result . discardedDest = dest . discarded ; } return result ; }
Compare two arrays of objects and return the added/removed/modified objects
 options:
 - key: name of the key (mandatory)
 - exclude: optional list of excluded key (not compared)
 - keep: optional list of keys copied (before comparing) from orig to dest
Compare two arrays of objects and return the added / removed / modified objects options : - key : name of the key ( mandatory ) - exclude : optional list of excluded key ( not compared ) - keep : optional list of keys copied ( before comparing ) from orig to dest
// keep and exclude // compare // discarded object (without a key) // for (i = 0; i < orig.discarded.length; i =+ 1) { //     t = orig.discarded[i]; // }