如何根据目标对象的键在javascript中合并两个嵌套对象?

如何根据目标对象的键在javascript中合并两个嵌套对象?,javascript,javascript-objects,Javascript,Javascript Objects,我有两个对象,一个是超集,另一个是子集。子集保证具有与超集相似的结构,只是子集将缺少超集中的某些属性 var superset = { car: { type: 'SUV', brand: 'Volvo', color: 'Black' }, features: { interior: { seats: 'leather', color: 'black'

我有两个对象,一个是超集,另一个是子集。子集保证具有与超集相似的结构,只是子集将缺少超集中的某些属性

var superset = {
    car: {
        type: 'SUV',
        brand: 'Volvo',
        color: 'Black'
    },
    features: {
        interior: {
            seats: 'leather',
            color: 'black'
        },
        exterior: {
            windows: 'tinted'
        },
        doors: 5
    },
    warranty: '5 yrs'
}

var subset = {
    car: {
        type: true,
        brand: true        
    },
    features: {
        interior: {
            seats: true            
        },
        exterior: {
            windows: true
        },
        doors: true
    }
}
var superset = {
    car: {
        type: 'SUV',
        brand: 'Volvo',
        color: 'Black'
    },
    features: {
        interior: {
            seats: 'leather',
            color: 'black'
        },
        exterior: {
            windows: 'tinted'
        },
        doors: 5
    },
    warranty: '5 yrs'
};

var subset = {
    car: {
        type: true,
        brand: true        
    },
    features: {
        interior: {
            seats: true            
        },
        exterior: {
            windows: true
        },
        doors: true
    }
};


var merge = function(data, keys_obj, result)
{
    for (key in keys_obj)
    {
        if (data.hasOwnProperty(key))
        {
            if (typeof(data[key]) == "object")
            {
                result[key] = {};
                merge(data[key], keys_obj[key], result[key]);
            }
            else if (data[key])
                result[key] = data[key];
        }
        //else you can throw an exception here: malformed subset
    }
};

function test()
{
    var result = {};
    merge(superset, subset, result);

    console.log(result);
}
我希望使用超集中的值合并这两个对象,但仅合并子集中存在的属性。结果如下所示:

{
    car: {
        type: 'SUV',
        brand: 'Volvo'
    },
    features: {
        interior: {
            seats: 'leather'
        },
        exterior: {
            windows: 'tinted'
        },
        doors: 5
    }
}
来自Lodash的
mergeWith
几乎可以完成这项工作,但它似乎只适用于以下第一级属性。这个想法是,一旦我为所有不需要的属性指定了一个唯一的值,我就可以循环并在以后除去它们

_.mergeWith(subset, superset, function(a, b) {return a ? b : 'DELETE'})

Result:
{
    car: {
        type: 'SUV',
        brand: 'Volvo',
        color: 'Black'
    },
    features: {
        interior: {
            seats: 'leather',
            color: 'black'
        },
        exterior: {
            windows: 'tinted'
        },
        doors: 5
    },
    warranty: 'DELETE'
}

感谢您的帮助。

此解决方案只需遍历
子集(我称之为
模式
),并从
超集
(我称之为
输入
)复制值(如果存在)。如果一个值在这两个值中都是对象,则函数将调用自身来处理嵌套属性:

函数合并(输入,模式){
var result={}
for(模式中的var k){
if(输入[k]&&typeof输入[k]=='object'&&schema[k]&&typeof schema[k]=='object'){
结果[k]=合并(输入[k],模式[k])
}else if(输入中的k){
结果[k]=输入[k]
}
}
返回结果
}
变量超集={
汽车:{
类型:“SUV”,
品牌:“沃尔沃”,
颜色:“黑色”
},
特点:{
内部:{
座椅:“真皮”,
颜色:“黑色”
},
外部:{
窗户:“有色的”
},
门:5
},
保修期:“5年”
}
变量子集={
汽车:{
类型:对,
品牌:真的
},
特点:{
内部:{
座位:对
},
外部:{
windows:是的
},
门:是的
}
}
var结果=合并(超集、子集)

log(result)
此解决方案只需遍历
子集(我称之为
schema
),并复制
超集(我称之为
input
)中存在的值。如果一个值在这两个值中都是对象,则函数将调用自身来处理嵌套属性:

函数合并(输入,模式){
var result={}
for(模式中的var k){
if(输入[k]&&typeof输入[k]=='object'&&schema[k]&&typeof schema[k]=='object'){
结果[k]=合并(输入[k],模式[k])
}else if(输入中的k){
结果[k]=输入[k]
}
}
返回结果
}
变量超集={
汽车:{
类型:“SUV”,
品牌:“沃尔沃”,
颜色:“黑色”
},
特点:{
内部:{
座椅:“真皮”,
颜色:“黑色”
},
外部:{
窗户:“有色的”
},
门:5
},
保修期:“5年”
}
变量子集={
汽车:{
类型:对,
品牌:真的
},
特点:{
内部:{
座位:对
},
外部:{
windows:是的
},
门:是的
}
}
var结果=合并(超集、子集)

console.log(result)
一个简单的递归函数,使用所需的键在对象中运行,如果每个键都存在于数据对象(超集)中,则如果result不是对象,则为其赋值,否则调用自身对该位置的子对象执行完全相同的操作。 如果keys对象的格式不正确,也就是说,如果它包含的键不在超集中的任何位置,那么还可以改进它以返回错误

var superset = {
    car: {
        type: 'SUV',
        brand: 'Volvo',
        color: 'Black'
    },
    features: {
        interior: {
            seats: 'leather',
            color: 'black'
        },
        exterior: {
            windows: 'tinted'
        },
        doors: 5
    },
    warranty: '5 yrs'
}

var subset = {
    car: {
        type: true,
        brand: true        
    },
    features: {
        interior: {
            seats: true            
        },
        exterior: {
            windows: true
        },
        doors: true
    }
}
var superset = {
    car: {
        type: 'SUV',
        brand: 'Volvo',
        color: 'Black'
    },
    features: {
        interior: {
            seats: 'leather',
            color: 'black'
        },
        exterior: {
            windows: 'tinted'
        },
        doors: 5
    },
    warranty: '5 yrs'
};

var subset = {
    car: {
        type: true,
        brand: true        
    },
    features: {
        interior: {
            seats: true            
        },
        exterior: {
            windows: true
        },
        doors: true
    }
};


var merge = function(data, keys_obj, result)
{
    for (key in keys_obj)
    {
        if (data.hasOwnProperty(key))
        {
            if (typeof(data[key]) == "object")
            {
                result[key] = {};
                merge(data[key], keys_obj[key], result[key]);
            }
            else if (data[key])
                result[key] = data[key];
        }
        //else you can throw an exception here: malformed subset
    }
};

function test()
{
    var result = {};
    merge(superset, subset, result);

    console.log(result);
}

一个简单的递归函数,使用所需的键在对象中运行,如果每个键都存在于数据对象(超集)中,则如果它不是对象,则将值赋给result,否则调用自身对该位置的子对象执行完全相同的操作。 如果keys对象的格式不正确,也就是说,如果它包含的键不在超集中的任何位置,那么还可以改进它以返回错误

var superset = {
    car: {
        type: 'SUV',
        brand: 'Volvo',
        color: 'Black'
    },
    features: {
        interior: {
            seats: 'leather',
            color: 'black'
        },
        exterior: {
            windows: 'tinted'
        },
        doors: 5
    },
    warranty: '5 yrs'
}

var subset = {
    car: {
        type: true,
        brand: true        
    },
    features: {
        interior: {
            seats: true            
        },
        exterior: {
            windows: true
        },
        doors: true
    }
}
var superset = {
    car: {
        type: 'SUV',
        brand: 'Volvo',
        color: 'Black'
    },
    features: {
        interior: {
            seats: 'leather',
            color: 'black'
        },
        exterior: {
            windows: 'tinted'
        },
        doors: 5
    },
    warranty: '5 yrs'
};

var subset = {
    car: {
        type: true,
        brand: true        
    },
    features: {
        interior: {
            seats: true            
        },
        exterior: {
            windows: true
        },
        doors: true
    }
};


var merge = function(data, keys_obj, result)
{
    for (key in keys_obj)
    {
        if (data.hasOwnProperty(key))
        {
            if (typeof(data[key]) == "object")
            {
                result[key] = {};
                merge(data[key], keys_obj[key], result[key]);
            }
            else if (data[key])
                result[key] = data[key];
        }
        //else you can throw an exception here: malformed subset
    }
};

function test()
{
    var result = {};
    merge(superset, subset, result);

    console.log(result);
}

谢谢@dodov,这很有帮助。感谢您的时间。谢谢@dodov,这很有帮助。谢谢你的时间。