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]
.
上一篇: 检查json对象内是否存在键
下一篇: 如何做两个对象与lodash深入比较?