Javascript 递归地遍历嵌套对象以进行深度复制,并从单独的数据源应用默认值
好吧,这一个可能是个傻瓜。我正在努力,但不知道是否有一个优雅的方式来处理这个问题 我有一个资产对象,每个对象都有一些属性,以及两个可能对象中的一些子资产:资产和特征 我还有一个平面对象,其中存储了每种类型的资产的默认值 我希望遍历对象,从ID检测我正在查看的资产类型,从flat defaults对象加载属性,覆盖嵌套对象中存在的任何属性,并返回一个新的嵌套对象,该对象具有所有默认值,但也使用原始嵌套对象中存在的任何内容进行更新 例如,嵌套对象:Javascript 递归地遍历嵌套对象以进行深度复制,并从单独的数据源应用默认值,javascript,object,Javascript,Object,好吧,这一个可能是个傻瓜。我正在努力,但不知道是否有一个优雅的方式来处理这个问题 我有一个资产对象,每个对象都有一些属性,以及两个可能对象中的一些子资产:资产和特征 我还有一个平面对象,其中存储了每种类型的资产的默认值 我希望遍历对象,从ID检测我正在查看的资产类型,从flat defaults对象加载属性,覆盖嵌套对象中存在的任何属性,并返回一个新的嵌套对象,该对象具有所有默认值,但也使用原始嵌套对象中存在的任何内容进行更新 例如,嵌套对象: { "id": "
{
"id": "Bohemian Rhapsody",
"version": "0.10.1.5",
"manifest": "6s43qhuy53as980u08647ugp864q867-08d4svbn9uh54xc8vu",
"slug": "DarkShiftingBolt",
"visibility": "friends",
"locked": true,
"values": {"value0":2},
"assets": [
{
"id": "I see",
"assets": [
{
"id": "a little",
"name": "Queen",
"values": {
"value1": 1,
"value2": 3,
"value3": 2
},
"characteristics": [
{
"id": "silhouetto",
"assets": [
{
"id": "of a man",
"values": {
"value4": 3,
"value5": 1
},
"assets": [
{"id": "Scaramouche"}
]
}
]
}
],
"assets": [
{"id": "Scaramouche"}
]
},
{
"id": "will you",
"name": "Freddy",
"values": {
"value1": 1,
"value2": 0,
"value3": 3
},
"assets": [
{
"id": "do the",
"assets": [
{"id": "fandango"}
]
}
]
}
]
}
]
}
平面默认对象:
{
"Bohemian Rhapsody": {
"visibility": "hidden",
"locked": false,
"values": {"value0":1},
},
"I see": {
"cost": 4
},
"a little": {
"values": {
"value2": 1,
"value4": 5
},
},
"silhouetto": {
"cost": 1
},
"of a man": {
"genre": "opera"
},
"Scaramouche": {
"rank": 3
},
"will you": {
"values": {
"value4": 0
},
},
"do the": {
"signature": [[4,4],[2,4],[6,8]]
},
"fandango": {
"records": ["thunderbolts","lightning"]
}
}
所需的输出对象:
{
"id": "Bohemian Rhapsody",
"version": "0.10.1.5",
"manifest": "6s43qhuy53as980u08647ugp864q867-08d4svbn9uh54xc8vu",
"slug": "DarkShiftingBolt",
"visibility": "hidden",
"locked": false,
"values": {"value0":1},
"assets": [
{
"id": "I see",
"cost": 4,
"assets": [
{
"id": "a little",
"name": "Queen",
"values": {
"value1": 1,
"value2": 1,
"value3": 2,
"value4": 5
},
"characteristics": [
{
"id": "silhouetto",
"assets": [
{
"id": "of a man",
"genre": "opera",
"values": {
"value4": 3,
"value5": 1
},
"assets": [
{
"id": "Scaramouche",
"rank": 3
}
]
}
]
}
],
"assets": [
{
"id": "Scaramouche",
"rank": 3
}
]
},
{
"id": "will you",
"name": "Freddy",
"values": {
"value1": 1,
"value2": 0,
"value3": 3,
"value4": 0
},
"assets": [
{
"id": "do the",
"signature": [[4,4],[2,4],[6,8]],
"assets": [
{
"id": "fandango",
"records": ["thunderbolts","lightning"]
}
]
}
]
}
]
}
]
}
我尝试的是一个object.keys递归函数,它根据找到的属性构建一个新对象。我很想知道是否有更聪明的方法来解决这个问题。多亏了@rayhatfield
import * as merge from 'deepmerge';
this.manifest = (manifestData as any).default;
this.list = (listData as any).default;
this.list = this.assetIterate(this.list);
assetIterate(asset){
let id = asset.id;
let type = this.manifest.asset_catalog[id].type;
let newAsset = merge.all([this.manifest.asset_taxonomy[type],this.manifest.asset_catalog[id],asset])
Object.keys(asset).forEach((key) => {
if(key === "characteristics" || key === "assets"){
newAsset[key] = [...asset[key]]
newAsset[key].forEach((asset,index) => {
newAsset[key][index] = this.assetIterate(asset);
});
}
});
asset = {...newAsset}
return asset
}
似乎适用于所有情况,除了子数组需要替换索引而不是串联索引的情况,但我可以在特殊情况下,当我实际制作其中一个索引时。如果您不想自己动手,可以使用现成的解决方案,如。@rayhatfield谢谢,这几乎适用于所有情况(还有一些重复的垃圾)