我有2个不同的嵌套对象,我需要知道它们是否在其中一个嵌套属性中有不同。
var a = {};
var b = {};
a.prop1 = 2;
a.prop2 = { prop3: 2 };
b.prop1 = 2;
b.prop2 = { prop3: 3 };
对象可以更复杂,有更多嵌套的属性。但这是一个很好的例子。我可以选择使用递归函数或lodash的东西…
我有2个不同的嵌套对象,我需要知道它们是否在其中一个嵌套属性中有不同。
var a = {};
var b = {};
a.prop1 = 2;
a.prop2 = { prop3: 2 };
b.prop1 = 2;
b.prop2 = { prop3: 3 };
对象可以更复杂,有更多嵌套的属性。但这是一个很好的例子。我可以选择使用递归函数或lodash的东西…
当前回答
我尝试了Adam Boduch的代码来输出一个很深的差异-这完全没有经过测试,但碎片在那里:
function diff (obj1, obj2, path) {
obj1 = obj1 || {};
obj2 = obj2 || {};
return _.reduce(obj1, function(result, value, key) {
var p = path ? path + '.' + key : key;
if (_.isObject(value)) {
var d = diff(value, obj2[key], p);
return d.length ? result.concat(d) : result;
}
return _.isEqual(value, obj2[key]) ? result : result.concat(p);
}, []);
}
diff({ foo: 'lol', bar: { baz: true }}, {}) // returns ["foo", "bar.baz"]
其他回答
如果你需要知道哪些属性是不同的,使用reduce():
_.reduce(a, function(result, value, key) {
return _.isEqual(value, b[key]) ?
result : result.concat(key);
}, []);
// → [ "prop2" ]
var isEqual = function(f,s) {
if (f === s) return true;
if (Array.isArray(f)&&Array.isArray(s)) {
return isEqual(f.sort(), s.sort());
}
if (_.isObject(f)) {
return isEqual(f, s);
}
return _.isEqual(f, s);
};
我需要知道它们的某个嵌套属性是否不同
其他答案为这个问题提供了可能令人满意的解决方案,但它非常困难和常见,似乎有一个非常受欢迎的包来帮助解决这个问题。
要使用这个包,你需要npm i deep-object-diff,然后:
const { diff } = require('deep-object-diff');
var a = {};
var b = {};
a.prop1 = 2;
a.prop2 = { prop3: 2 };
b.prop1 = 2;
b.prop2 = { prop3: 3 };
if (!_.isEqual(a, b)) {
const abDiff = diff(a, b);
console.log(abDiff);
/*
{
prop2: {
prop3: 3
}
}
*/
}
// or alternatively
const abDiff = diff(a, b);
if(!_.isEmpty(abDiff)) {
// if a diff exists then they aren't deeply equal
// perform needed actions with diff...
}
下面是一个更详细的案例,直接从他们的文档中删除属性:
const lhs = {
foo: {
bar: {
a: ['a', 'b'],
b: 2,
c: ['x', 'y'],
e: 100 // deleted
}
},
buzz: 'world'
};
const rhs = {
foo: {
bar: {
a: ['a'], // index 1 ('b') deleted
b: 2, // unchanged
c: ['x', 'y', 'z'], // 'z' added
d: 'Hello, world!' // added
}
},
buzz: 'fizz' // updated
};
console.log(diff(lhs, rhs)); // =>
/*
{
foo: {
bar: {
a: {
'1': undefined
},
c: {
'2': 'z'
},
d: 'Hello, world!',
e: undefined
}
},
buzz: 'fizz'
}
*/
有关实现细节和其他使用信息,请参阅该repo。
作为对亚当·博杜赫的回答的补充,这个问题考虑到了性质的差异
const differenceOfKeys = (...objects) =>
_.difference(...objects.map(obj => Object.keys(obj)));
const differenceObj = (a, b) =>
_.reduce(a, (result, value, key) => (
_.isEqual(value, b[key]) ? result : [...result, key]
), differenceOfKeys(b, a));
已经有很多答案发布,但对于那些好奇的人来说,避免编写任何代码来计算具有任何类型结构的两个对象之间的差异,实际上有一个库可以做到这一点。Lodash isEqual只返回true或false,它不返回任何关于更改属性的信息。https://www.npmjs.com/package/deep-diff
它返回两个对象之间差异的完整细节
import DeepDiff from 'deep-diff';
let a = {...} //some object
let b = {...} //some object
var differences = DeepDiff.diff(a, b);
在这篇文章中也有人提出了类似的问题 获取2个JSON对象之间的差异