How to do a deep comparison between 2 objects with lodash?

I have 2 nested objects which are different and I need to know if they have difference in one of their nested properties.

var a = {};
var b = {};

a.prop1 = 2;
a.prop2 = { prop3: 2 };

b.prop1 = 2;
b.prop2 = { prop3: 3 };

The object could be much more complex with more nested properties. But this one is a good example. I have the option to use recursive functions or something with lodash...


An easy and elegant solution is to use _.isEqual , which performs a deep comparison:

var a = {};
var b = {};

a.prop1 = 2;
a.prop2 = { prop3: 2 };

b.prop1 = 2;
b.prop2 = { prop3: 3 };

_.isEqual(a, b); // returns false if different

However, this solution doesn't show which property is different.

http://jsfiddle.net/bdkeyn0h/


如果您需要知道哪些属性不同,请使用reduce():

_.reduce(a, function(result, value, key) {
    return _.isEqual(value, b[key]) ?
        result : result.concat(key);
}, []);
// → [ "prop2" ]

For anyone stumbling upon this thread, here's a more complete solution. It will compare two objects and give you the key of all properties that are either only in object1 , only in object2 , or are both in object1 and object2 but have different values :

/*
 * Compare two objects by reducing an array of keys in obj1, having the
 * keys in obj2 as the intial value of the result. Key points:
 *
 * - All keys of obj2 are initially in the result.
 *
 * - If the loop finds a key (from obj1, remember) not in obj2, it adds
 *   it to the result.
 *
 * - If the loop finds a key that are both in obj1 and obj2, it compares
 *   the value. If it's the same value, the key is removed from the result.
 */
function getObjectDiff(obj1, obj2) {
    const diff = Object.keys(obj1).reduce((result, key) => {
        if (!obj2.hasOwnProperty(key)) {
            result.push(key);
        } else if (_.isEqual(obj1[key], obj2[key])) {
            const resultKeyIndex = result.indexOf(key);
            result.splice(resultKeyIndex, 1);
        }
        return result;
    }, Object.keys(obj2));

    return diff;
}

Here's an example output:

// Test
let obj1 = {
    a: 1,
    b: 2,
    c: { foo: 1, bar: 2},
    d: { baz: 1, bat: 2 }
}

let obj2 = {
    b: 2, 
    c: { foo: 1, bar: 'monkey'}, 
    d: { baz: 1, bat: 2 }
    e: 1
}
getObjectDiff(obj1, obj2)
// ["c", "e", "a"]

If you don't care about nested objects and want to skip lodash, you can substitute the _.isEqual for a normal value comparison, eg obj1[key] === obj2[key] .

链接地址: http://www.djcxy.com/p/26636.html

上一篇: 检查json对象内是否存在键

下一篇: 如何做两个对象与lodash深入比较?