比较两个深嵌套对象,只返回javascript/lodash中的差异

比较两个深嵌套对象,只返回javascript/lodash中的差异,javascript,node.js,lodash,javascript-objects,Javascript,Node.js,Lodash,Javascript Objects,我有两个深嵌套的对象。一个是“基本”对象,另一个是修改对象 我基本上希望从修改过的对象中“删除”基本对象,并返回一个只包含不同数据的对象。以下是一个例子: 基本对象: baseObj : { image: { width: '100%', paddingTop: '0px', paddingRight: '0px', paddingBottom: '0px', paddingLeft: '0px' }

我有两个深嵌套的对象。一个是“基本”对象,另一个是修改对象

我基本上希望从修改过的对象中“删除”基本对象,并返回一个只包含不同数据的对象。以下是一个例子:

基本对象:

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或其他库?

您可以使用递归函数查找最后一个对象

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)
您可以从中验证结果


注意:您需要根据reduce中的要求调整结果。此结果与您的输出相匹配。

您可以使用递归函数查找最后一个对象

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)
您可以从中验证结果


注意:您需要根据reduce中的要求调整结果。此结果与您的输出匹配。

要解决此问题,我们必须:

  • 创建递归遍历对象中每个节点的函数。我们可以在遍历
    对象时使用函数来实现这一点
  • reduce
    回调函数将首先检查
    值或其
    其他
    值计数器部分是否都是对象。如果是,我们将使用这些值作为参数,递归地获取这两个对象的差异。否则,如果它们不同,则我们将从
    其他值中指定结果值
  • 最后,
    reduce
    函数接受第三个参数,该参数用作
    reduce
    函数的累积值的初始值。我们用
    其他
    对象中的键值分配第三个参数,这些键值在
    对象中找不到。这是从
    其他
    对象中获取新引入的值到结果对象的最简单方法

var数据={
baseObj:{
图片:{
宽度:“100%”,
paddingTop:'0px',
填充右侧:“0px”,
填充底部:“0px”,
左填充:“0px”
},
包裹:{
marginTop:'0px',
marginRight:“0px”,
marginBottom:'0px',
marginLeft:'0px'
}
},
合并对象:{
图片:{
宽度:“100%”,
paddingTop:'0px',
paddingRight:'24px',//修改值
paddingBottom:'24px',//修改值
左填充:“0px”
},
包裹:{
高度:“100px”,//新值
marginTop:'24px',//修改值
marginRight:“0px”,
marginBottom:'0px',
marginLeft:'24px'//修改值
}
}
};
函数差异对象深度(源、其他){
返回u.reduce(源、函数(结果、值、键){
if(u.isObject(值)和&u.isObject(其他[键]){
结果[键]=差异对象深度(
价值
其他[关键]
);
}else if(!\ isEqual(值,其他[键]){
结果[键]=其他[键];
}
返回结果;
}、省略(其他、、键(源));
}
data.diffObject=差异对象深度(
data.baseObj,
data.mergedObject
);
console.log(data.diffObject)
body>div{
最小高度:100%;
排名:0;
}

要解决这个问题,我们必须:

  • 创建递归遍历对象中每个节点的函数。我们可以在遍历
    对象时使用函数来实现这一点
  • reduce
    回调函数将首先检查
    值或其
    其他
    值计数器部分是否都是对象。如果是,我们将使用这些值作为参数,递归地获取这两个对象的差异。否则,如果它们不同,则我们将从
    其他值中指定结果值
  • 最后,
    reduce
    函数接受第三个参数,该参数用作
    reduce
    函数的累积值的初始值。我们用
    其他
    对象中的键值分配第三个参数,这些键值在
    对象中找不到。这是从
    其他
    对象中获取新引入的值到结果对象的最简单方法

var数据={
baseObj:{
图片:{
宽度:“100%”,
paddingTop:'0px',
填充右侧:“0px”,
填充底部:“0px”,
左填充:“0px”
},
包裹:{
marginTop:'0px',
marginRight:“0px”,
marginBottom:'0px',
marginLeft:'0px'
}
},
合并对象:{
图片:{
宽度:“100%”,
paddingTop:'0px',
paddingRight:'24px',//修改值
paddingBottom:'24px',//修改值
左填充:“0px”
},
包裹:{
高度:“100px”,//新值
marginTop:'24px',//修改值
marginRight:“0px”,
marginBottom:'0px',
marginLeft:'24px'//修改值
}
}
};
函数差异对象深度(源、其他){
返回u.reduce(源、函数(结果、值、键){
if(u.isObject(值)和&u.isObject(其他[键]){
结果[键]=差异对象深度(
价值
其他[关键]
);
}else if(!\ isEqual(值,其他[键]){
结果[键]=其他[键];
}
返回结果;
}、省略(其他、、键(源));
}
data.diffObject=差异对象深度(
data.baseObj,
data.mergedObject
);
console.log(data.diffObject)
body>div{
最小高度:100%;
排名:0;
}

可能重复感谢。我在那个页面上找到了一个JSFIDLE:它几乎满足了我的需要。但是,它返回空对象,例如:“diff(a,b)=“{”x:4,“z”:{},“zz”:{”a:1,“b:2}}”diff(a,b)=“{”x:56,“z”:{},“zz”:{”a:2,“b:1}。如果我能找到删除z:{}值的方法,那么它可能是