递归减去两个JavaScript对象
让我们创建一个具有一些默认设置的对象:递归减去两个JavaScript对象,javascript,recursion,Javascript,Recursion,让我们创建一个具有一些默认设置的对象: var defaults = { id: '', x: 0, y: 0, width: 20, height: 20, styles: { color: '#ffffff', background_color: '#000000' }, points: [] } 然后,我们创建自己的对象,该对象最初扩展了默认设置,并进行了一些更改: var newObject
var defaults = {
id: '',
x: 0,
y: 0,
width: 20,
height: 20,
styles: {
color: '#ffffff',
background_color: '#000000'
},
points: []
}
然后,我们创建自己的对象,该对象最初扩展了默认设置,并进行了一些更改:
var newObject = {
id: '1', // changed
x: 10, // changed
y: 10, // changed
width: 20,
height: 20,
styles: {
color: '#ffffff',
background_color: '#333333' // changed
},
points: [1, 2, 3]
}
最后,我们需要一个对象,它只包含从默认设置更改的值,如下所示:
var subtracted = {
id: '1',
x: 10,
y: 10,
styles: {
background_color: '#333333'
},
points: [1, 2, 3]
}
算法需要递归,对象中可以有对象。以下是我到目前为止的情况:
function subtract(a, b) {
var r = {};
// For each property of 'b'
// if it's different than the corresponding property of 'a'
// place it in 'r'
for (var key in b) {
if (typeof(b[key]) == 'object') {
if (!a[key]) a[key] = {};
r[key] = subtract(a[key], b[key]);
} else {
if (b[key] != a[key]) {
r[key] = a[key];
}
}
}
return r;
}
然而,递归对数组不起作用,所以“点”变成了一个空对象!typeof()将其检测为对象,但不知何故未能克隆其属性
您的代码正在运行。虽然我对它做了一次编辑,使它也具有递归性
var默认值={
id:“”,
x:0,,
y:0,
宽度:20,
身高:20,
风格:{
颜色:“#ffffff”,
背景颜色:'#000000'
},
要点:[]
}
var newObject={
id:'1',//已更改
x:10,//已更改
y:10,//改变了
宽度:20,
身高:20,
风格:{
颜色:“#ffffff”,
背景颜色:'#333333'//已更改
},
点数:[0,1,2]//已更改
}
减去var={
id:'1',
x:10,
y:10,
风格:{
背景颜色:“#333333”
}
}
函数名(a,b){
如果(a.length!=b.length)返回false;
if(a.filter(函数(i){返回a.indexOf(i)<0;}).length>0)
返回false;
if(b.filter(函数(i){返回a.indexOf(i)<0;}).length>0)
返回false;
返回true;
};
函数减法(a,b){
var r={};
//对于“b”的每个属性
//如果它与“a”的相应属性不同
//将其置于“r”中
for(b中的var键){
if(Array.isArray(b[key])){
如果(!a[key])a[key]=[];
如果(!IsName(a[key],b[key]))
r[key]=a[key];
}else if(typeof(b[key])=='object'){
如果(!a[key])a[key]={};
r[键]=减法(a[键]、b[键]);
}否则{
如果(b[键]!=a[键]){
r[key]=a[key];
}
}
}
返回r;
}
log(减去(newObject,默认值))代码>更新:另一种更接近递归的方法。它通过修改运行,因此newObject可以忽略某些字段。它也适用于原语
const equalArrays=(arr1,arr2)=>arr1.length==arr2.length&&arr1.every((元素,索引)=>element==arr2[index])
//请注意,EqualArray影响数组元素的顺序。
//如果顺序不重要,请考虑首先将两个数组排序。
const isObject=(obj)=>对象的obj实例&!(阵列的obj实例)
//请注意,数组也是对象的实例
//不小心的使用者可能会将数组和对象混合在一起,从而产生不可预知的结果
常量isArray=(arr)=>arr数组实例
常量getDifferences=(原始、修改)=>{
const Arearray=isArray(原始)和&isArray(修改)
常量对象=isObject(原始)和isObject(修改)
如果(对象){
让结果={}
for(对象的常量键。键(已修改)){
const diff=getDifferences(原始[键]、修改[键])
如果(差异)结果[键]=差异
}
return!!Object.keys(result).length&&result
}
else if(areArrays&!equalarray(原始,修改))返回修改
否则如果(原始!==修改)返回修改
}
//请注意,有些变量和函数是为了可读性而存在的,可能是内联的
设默认值={
id:“”,
x:0,,
y:0,
宽度:20,
身高:20,
风格:{
颜色:“#ffffff”,
背景颜色:'#000000'
},
要点:[]
}
让newObject={
id:'1',//已更改
x:10,//已更改
y:10,//改变了
宽度:20,
身高:20,
风格:{
颜色:“#ffffff”,
背景颜色:'#333333'//已更改
},
点数:[0,1,2]//已更改
}
log(getDifferences(默认值,newObject))
是的,当然!网站不允许我马上接受。干杯不幸的是,如果对象中存在数组,则此操作不起作用:/