[英]Compare two deep nested object of objects and return only the differences in javascript / lodash
I have 2 deep nested object of objects. 我有2个对象的深层嵌套对象。 One is a "base" object and the other is a modified one.
一个是“基础”对象,另一个是经过修改的对象。
I essentially want to "delete" the base object from the modified object and return an object that only contains different data. 我本质上是想从修改后的对象中“删除”基础对象,并返回仅包含不同数据的对象。 Here is an example:
这是一个例子:
Base object: 基础对象:
baseObj : {
image: {
width: '100%',
paddingTop: '0px',
paddingRight: '0px',
paddingBottom: '0px',
paddingLeft: '0px'
},
wrap: {
marginTop: '0px',
marginRight: '0px',
marginBottom: '0px',
marginLeft: '0px'
}
}
Object with modified data 具有修改数据的对象
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
}
}
I would like an object that is returned like this: 我想要这样返回的对象:
diffObject : {
image: {
paddingRight: '24px',
paddingBottom: '24px',
},
wrap: {
height: '100px',
marginTop: '24px',
marginLeft: '24px'
}
}
The nesting could go a little deeper so it needs to be dynamic. 嵌套可能会更深一些,因此它必须是动态的。 Is there a way using lodash or some other library?
有没有办法使用lodash或其他一些库?
To solve this problem, we must: 为了解决这个问题,我们必须:
source
object. source
对象时使用reduce函数来实现此目的。 reduce
callback function would first check if the source
value or it's other
value counter part are both objects. reduce
回调函数将首先检查source
值或其other
值计数器部分是否都是对象。 If they are, we'll use these values as arguments to recursively get the difference of both these objects. other
value. other
值中分配结果值。 reduce
function accepts a third argument which is used as the initial value for the accumulated of the reduce
function. reduce
函数接受第三个参数,该参数用作reduce
函数累加的初始值。 We assign the third argument with key-values from the other
object that aren't found in the source
object. source
对象中找不到的other
对象的键值。 This is the simplest way to get the newly introduced values from the other
object towards the resulting object. 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>
you could use recursive function to find the last object. 您可以使用递归函数查找最后一个对象。
var checkIfObject = function(item){ //recursive function
_.each(item, function(v, k){
if(_.isObject(v)){
previousObject = k;
previousResult = v;
return checkIfObject(v);
}else{
finalChildObjects[previousObject] = previousResult;
}
})
return finalChildObjects
}
/*Initialize Values for recursive function*/
var finalChildObjects = {};
var previousObject = '';
var previousResult = '';
baseObjectFinalTurn = checkIfObject(baseObj);
/*Initialize Values for recursive function*/
var finalChildObjects = {};
var previousObject = '';
var previousResult = '';
mergedObjectFinalTurn = checkIfObject(mergedObject);
console.clear();
var difference = {};
_.each(baseObjectFinalTurn, function(v, k){
if(mergedObjectFinalTurn[k]){
difference[k] = _.reduce(mergedObjectFinalTurn[k],function(result, value, key){
if(baseObjectFinalTurn[k][key] != mergedObjectFinalTurn[k][key]){
result[key] = value;
}
return result
}, {})
}
else{
difference[k] = {};
}
})
console.log(difference)
You can verify the result from this jsfiddle link 您可以从此jsfiddle链接验证结果
Note: you need to adjust the result based on your requirement in reduce. 注意:您需要根据reduce的要求调整结果。 This result is made to match your output.
该结果与您的输出相匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.