我有 2 个深层嵌套的对象。一个是“基础”对象,另一个是修改后的对象。
我本质上是想从修改的对象中“删除”基础对象并返回一个仅包含不同数据的对象。这是一个例子:
基础对象:
baseObj : {
image: {
width: '100%',
paddingTop: '0px',
paddingRight: '0px',
paddingBottom: '0px',
paddingLeft: '0px'
},
wrap: {
marginTop: '0px',
marginRight: '0px',
marginBottom: '0px',
marginLeft: '0px'
}
}
具有修改数据的对象
mergedObject : {
image: {
width: '100%',
paddingTop: '0px',
paddingRight: '24px', // modified value
paddingBottom: '24px', // modified value
paddingLeft: '0px'
},
wrap: {
height: '100px', // new value
marginTop: '24px', // modified value
marginRight: '0px',
marginBottom: '0px',
marginLeft: '24px' // modified value
}
}
我想要一个像这样返回的对象:
diffObject : {
image: {
paddingRight: '24px',
paddingBottom: '24px',
},
wrap: {
height: '100px',
marginTop: '24px',
marginLeft: '24px'
}
}
嵌套可能会更深一点,因此它需要是动态的。有没有办法使用 lodash 或其他库?
最佳答案
要解决这个问题,我们必须:
- 创建一个递归遍历对象中每个 Node 的函数。我们可以通过使用reduce来实现这一点遍历
source
对象时的函数。 reduce
回调函数将首先检查source
值或其other
值对应部分是否都是对象。如果是,我们将使用这些值作为参数来递归地获取这两个对象的差异。否则,如果它们不同,我们将分配other
值的结果值。- 最后,
reduce
函数接受第三个参数,该参数用作reduce
函数累加的初始值。我们将other
对象中的键值分配给第三个参数,但在source
对象中找不到这些键值。这是从other
对象向结果对象获取新引入的值的最简单方法。
function differenceObjectDeep(source, other) {
return _.reduce(source, function(result, value, key) {
if (_.isObject(value) && _.isObject(other[key])) {
result[key] = differenceObjectDeep(
value,
other[key]
);
} else if (!_.isEqual(value, other[key])) {
result[key] = other[key];
}
return result;
}, _.omit(other, _.keys(source)));
}
data.diffObject = differenceObjectDeep(
data.baseObj,
data.mergedObject
);
var data = {
baseObj: {
image: {
width: '100%',
paddingTop: '0px',
paddingRight: '0px',
paddingBottom: '0px',
paddingLeft: '0px'
},
wrap: {
marginTop: '0px',
marginRight: '0px',
marginBottom: '0px',
marginLeft: '0px'
}
},
mergedObject: {
image: {
width: '100%',
paddingTop: '0px',
paddingRight: '24px', // modified value
paddingBottom: '24px', // modified value
paddingLeft: '0px'
},
wrap: {
height: '100px', // new value
marginTop: '24px', // modified value
marginRight: '0px',
marginBottom: '0px',
marginLeft: '24px' // modified value
}
}
};
function differenceObjectDeep(source, other) {
return _.reduce(source, function(result, value, key) {
if (_.isObject(value) && _.isObject(other[key])) {
result[key] = differenceObjectDeep(
value,
other[key]
);
} else if (!_.isEqual(value, other[key])) {
result[key] = other[key];
}
return result;
}, _.omit(other, _.keys(source)));
}
data.diffObject = differenceObjectDeep(
data.baseObj,
data.mergedObject
);
console.log(data.diffObject);
body>div {
min-height: 100%;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
关于javascript - 比较对象的两个深层嵌套对象并仅返回 javascript/lodash 中的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42281957/