我有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的东西…
当前回答
此解决方案返回一个具有修改过的属性的对象。
_.reduce(a, (r, v, k) => { return _.merge(r, _.isEqual(v, b[k]) ? {} : { [k]: v }); }, {});
其他回答
要递归地显示一个对象与其他对象的不同之处,可以使用_。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,它执行深度比较:
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 " > < /脚本>
然而,这个解决方案并没有显示哪个属性是不同的。
深度比较使用模板的(嵌套)属性进行检查
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)
这将在控制台中工作。如果需要,可以添加数组支持
如果你需要知道哪些属性是不同的,使用reduce():
_.reduce(a, function(result, value, key) {
return _.isEqual(value, b[key]) ?
result : result.concat(key);
}, []);
// → [ "prop2" ]
此解决方案返回一个具有修改过的属性的对象。
_.reduce(a, (r, v, k) => { return _.merge(r, _.isEqual(v, b[k]) ? {} : { [k]: v }); }, {});