我有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的东西…
当前回答
已经有很多答案发布,但对于那些好奇的人来说,避免编写任何代码来计算具有任何类型结构的两个对象之间的差异,实际上有一个库可以做到这一点。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对象之间的差异
其他回答
一个简单而优雅的解决方案是使用_。isEqual,它执行深度比较:
Var a = {}; Var b = {}; A.prop1 = 2; A.prop2 = {prop3: 2}; B.prop1 = 2; B.prop2 = {prop3: 3}; console.log(_。isEqual (a, b));//如果不同则返回false < script src = " https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js " > < /脚本>
然而,这个解决方案并没有显示哪个属性是不同的。
这是基于@JLavoie,使用lodash
let differences = function (newObj, oldObj) {
return _.reduce(newObj, function (result, value, key) {
if (!_.isEqual(value, oldObj[key])) {
if (_.isArray(value)) {
result[key] = []
_.forEach(value, function (innerObjFrom1, index) {
if (_.isNil(oldObj[key][index])) {
result[key].push(innerObjFrom1)
} else {
let changes = differences(innerObjFrom1, oldObj[key][index])
if (!_.isEmpty(changes)) {
result[key].push(changes)
}
}
})
} else if (_.isObject(value)) {
result[key] = differences(value, oldObj[key])
} else {
result[key] = value
}
}
return result
}, {})
}
https://jsfiddle.net/EmilianoBarboza/0g0sn3b9/8/
我知道这并不能直接回答OP的问题,但我是通过搜索如何删除lodash被引导到这里的。希望这能帮助到和我处境相似的人。
这要归功于@JohanPersson。我在这个答案的基础上实现了对深度嵌套值的比较,并获得对差异的键引用
getObjectDiff = (obj1, obj2) => { const obj1Props = Object.keys(obj1); const obj2Props = Object.keys(obj2); const keysWithDiffValue = obj1Props.reduce((keysWithDiffValueAccumulator, key) => { const propExistsOnObj2 = obj2.hasOwnProperty(key); const hasNestedValue = obj1[key] instanceof Object && obj2[key] instanceof Object; const keyValuePairBetweenBothObjectsIsEqual = obj1[key] === obj2[key]; if (!propExistsOnObj2) { keysWithDiffValueAccumulator.push(key); } else if (hasNestedValue) { const keyIndex = keysWithDiffValueAccumulator.indexOf(key); if (keyIndex >= 0) { keysWithDiffValueAccumulator.splice(keyIndex, 1); } const nestedDiffs = getObjectDiff(obj1[key], obj2[key]); for (let diff of nestedDiffs) { keysWithDiffValueAccumulator.push(`${key}.${diff}`); } } else if (keyValuePairBetweenBothObjectsIsEqual) { const equalValueKeyIndex = keysWithDiffValueAccumulator.indexOf(key); keysWithDiffValueAccumulator.splice(equalValueKeyIndex, 1); } return keysWithDiffValueAccumulator; }, obj2Props); return keysWithDiffValue; } const obj1 = {a0: {a1: {a2: {a3: 'Im here'}}}}; const obj2 = {a0: {a1: {a2: {a3: 'Not here', b3: 'some'}}}}; console.log('final', getObjectDiff(obj1, obj2));
这段代码返回一个具有不同值的所有属性的对象,以及两个对象的值。对记录差异很有用。
var allkeys = _.union(_.keys(obj1), _.keys(obj2));
var difference = _.reduce(allkeys, function (result, key) {
if ( !_.isEqual(obj1[key], obj2[key]) ) {
result[key] = {obj1: obj1[key], obj2: obj2[key]}
}
return result;
}, {});
已经有很多答案发布,但对于那些好奇的人来说,避免编写任何代码来计算具有任何类型结构的两个对象之间的差异,实际上有一个库可以做到这一点。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对象之间的差异