递归减去两个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))
是的,当然!网站不允许我马上接受。干杯不幸的是,如果对象中存在数组,则此操作不起作用:/