我有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的东西…
当前回答
以Sridhar Gudimela的回答为基础,下面以一种使用TypeScript的方式进行了更新:
/// U T I L S
interface LooseObjectInterface {
[key: string]: any;
};
type inputOptions = LooseObjectInterface | any[];
/// E X P O R T
export const objectCompare = (objectA: inputOptions, objectB: inputOptions): LooseObjectInterface => {
let diffObj: LooseObjectInterface = {};
switch(true) {
case (Array.isArray(objectA)):
objectA.forEach((elem: any, index: number) => {
if (!Array.isArray(diffObj))
diffObj = [];
diffObj[index] = objectCompare(elem, (objectB || [])[index]);
});
break;
case (objectA !== null && typeof objectA === "object"):
Object.keys(objectA).forEach((key: any) => {
if (Array.isArray(objectA[key])) {
let arr = objectCompare(objectA[key], objectB[key]);
if (!Array.isArray(arr))
arr = [];
arr.forEach((elem: any, index: number) => {
if (!Array.isArray(diffObj[key]))
diffObj[key] = [];
diffObj[key][index] = elem;
});
} else if (typeof objectA[key] === "object")
diffObj[key] = objectCompare(objectA[key], objectB[key]);
else if (objectA[key] !== (objectB || {})[key])
diffObj[key] = objectA[key];
else if (objectA[key] === (objectB || {})[key])
delete objectA[key];
});
break;
default:
break;
}
Object.keys(diffObj).forEach((key: any) => {
if (typeof diffObj[key] === "object" && JSON.stringify(diffObj[key]) === "{}")
delete diffObj[key];
});
return diffObj;
};
编辑:我最初的回答使用了Flow,因此被否决了(我猜,或者可能是因为我的回答没有使用Lodash……)然而,有一个类似问题的答案也无妨)。
其他回答
这是基于@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/
要递归地显示一个对象与其他对象的不同之处,可以使用_。Reduce与_结合。isEqual和_.isPlainObject。在这种情况下,你可以比较a与b的不同,或者b与a的不同:
const objectA = { a: { 1: "SAME WILL BE MISSING IN RESULT", 2: "BBB", 3: [1, 2, 3] }, b: "not", c: "foo bar" }; const objectB = { a: { 1: "SAME WILL BE MISSING IN RESULT", 2: [1, 2] }, b: "foo", c: "bar" }; const diff = function(obj1, obj2) { return _.reduce(obj1, function(result, value, key) { if (_.isPlainObject(value)) { result[key] = diff(value, obj2[key]); } else if (!_.isEqual(value, obj2[key])) { result[key] = value; } return result; }, {}); }; const diffAOverB = diff(objectA, objectB); const diffBOverA = diff(objectA, objectB); console.log(diffAOverB); console.log(diffBOverA); <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"></script>
简单使用_。isEqual方法,它将适用于所有比较…
注意:此方法支持比较数组、数组缓冲区、 布尔值、 *日期对象,错误对象,地图,数字,对象对象,正则表达式, *集合、字符串、符号和类型化数组。对象对象进行比较 *通过自身的,不可继承的,可枚举的属性。函数和DOM *节点不支持。
所以如果你有以下情况:
const firstName = {name: "Alireza"};
const otherName = {name: "Alireza"};
如果是:_。isEqual (firstName, otherName);
它会返回true
如果const fullName = {firstName: "Alireza", familyName: "Dezfoolian"};
如果是:_。isEqual (firstName, fullName);
将返回false
这段代码返回一个具有不同值的所有属性的对象,以及两个对象的值。对记录差异很有用。
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;
}, {});
作为对亚当·博杜赫的回答的补充,这个问题考虑到了性质的差异
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));