我有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/下划线的情况下,我已经编写了这段代码,并且可以很好地对object1和object2进行深入比较
function getObjectDiff(a, b) {
var diffObj = {};
if (Array.isArray(a)) {
a.forEach(function(elem, index) {
if (!Array.isArray(diffObj)) {
diffObj = [];
}
diffObj[index] = getObjectDiff(elem, (b || [])[index]);
});
} else if (a != null && typeof a == 'object') {
Object.keys(a).forEach(function(key) {
if (Array.isArray(a[key])) {
var arr = getObjectDiff(a[key], b[key]);
if (!Array.isArray(arr)) {
arr = [];
}
arr.forEach(function(elem, index) {
if (!Array.isArray(diffObj[key])) {
diffObj[key] = [];
}
diffObj[key][index] = elem;
});
} else if (typeof a[key] == 'object') {
diffObj[key] = getObjectDiff(a[key], b[key]);
} else if (a[key] != (b || {})[key]) {
diffObj[key] = a[key];
} else if (a[key] == (b || {})[key]) {
delete a[key];
}
});
}
Object.keys(diffObj).forEach(function(key) {
if (typeof diffObj[key] == 'object' && JSON.stringify(diffObj[key]) == '{}') {
delete diffObj[key];
}
});
return diffObj;
}
其他回答
简单使用_。isEqual方法,它将适用于所有比较…
注意:此方法支持比较数组、数组缓冲区、 布尔值、 *日期对象,错误对象,地图,数字,对象对象,正则表达式, *集合、字符串、符号和类型化数组。对象对象进行比较 *通过自身的,不可继承的,可枚举的属性。函数和DOM *节点不支持。
所以如果你有以下情况:
const firstName = {name: "Alireza"};
const otherName = {name: "Alireza"};
如果是:_。isEqual (firstName, otherName);
它会返回true
如果const fullName = {firstName: "Alireza", familyName: "Dezfoolian"};
如果是:_。isEqual (firstName, fullName);
将返回false
我知道这并不能直接回答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));
深度比较使用模板的(嵌套)属性进行检查
function objetcsDeepEqualByTemplate(objectA, objectB, comparisonTemplate) {
if (!objectA || !objectB) return false
let areDifferent = false
Object.keys(comparisonTemplate).some((key) => {
if (typeof comparisonTemplate[key] === 'object') {
areDifferent = !objetcsDeepEqualByTemplate(objectA[key], objectB[key], comparisonTemplate[key])
return areDifferent
} else if (comparisonTemplate[key] === true) {
areDifferent = objectA[key] !== objectB[key]
return areDifferent
} else {
return false
}
})
return !areDifferent
}
const objA = {
a: 1,
b: {
a: 21,
b: 22,
},
c: 3,
}
const objB = {
a: 1,
b: {
a: 21,
b: 25,
},
c: true,
}
// template tells which props to compare
const comparisonTemplateA = {
a: true,
b: {
a: true
}
}
objetcsDeepEqualByTemplate(objA, objB, comparisonTemplateA)
// returns true
const comparisonTemplateB = {
a: true,
c: true
}
// returns false
objetcsDeepEqualByTemplate(objA, objB, comparisonTemplateB)
这将在控制台中工作。如果需要,可以添加数组支持
作为对亚当·博杜赫的回答的补充,这个问题考虑到了性质的差异
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对象之间的差异