提问者:小点点

基于相同嵌套键合并嵌套JavaScript对象


抱歉,伙计们,我已经尝试了很长一段时间来改变下面的输入。

{
    "list": [
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "angular": {
                    "html": ""
                }
            }
        },
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "angular": {
                    "script": ""
                }
            }
        },
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "html": {
                    "html": ""
                }
            }
        },
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "html": {
                    "script": ""
                }
            }
        },
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "react": {
                    "script": ""
                }
            }
        },
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "vue": {
                    "script": ""
                }
            }
        },
    {
        "name": "light_with_header",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "vue": {
                "script": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "angular": {
                "html": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "angular": {
                "script": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "html": {
                "html": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "html": {
                "script": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "react": {
                "script": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "vue": {
                "script": ""
            }
        }
    },

    ]
}

输出,如下所示

{
    list: [
        {
            name: "light_with_header",
            path: "webapp/master_layouts/sidebar_layouts/",
            type: "Directory",
            data: {
                angular: {
                    html: "",
                    script: ""
                },
                html: {
                    html: "",
                    script: ""
                },
                react: {
                    script: ""
                },
                vue: {
                    "script": ""
                }
            }
        },
        {
          name: "light_with_header_and_icons",
          path: "webapp/master_layouts/sidebar_layouts/",
          type: "Directory",
           data: {
            angular: {
                html: "",
                script: ""
            },
            html: {
                html: "",
                script: ""
            },
            react: {
                script: ""
            },
            vue: {
                script: ""
            }

       },
  
    ]
}

我一直在努力想怎么做,但我不是很好

我尝试编写以下代码,但它返回一个空列表。如果属性相同,它应该合并这些对象。

var anotherList = list.reduce((prev,next)=>{
    let newList = mergeArrayObjects(prev,next)
    return newList
},[])

function mergeArrayObjects(arr1,arr2){
    return arr1.map((item,i)=>{
       if(item.name === arr2[i].name){
           //merging two objects
         return Object.assign({},item,arr2[i])
       }
    })
}

抱歉,但是任何参考,想法或相关代码都可能会很有帮助。我重新发布是因为我在尝试之后删除了我的旧的。


共2个答案

匿名用户

首先维护一个将ID映射到对象的对象,然后您可以稍后将其转换回列表:

const mappings = {};
const ordering = []; // maintain ordering and path/type fields
// assuming your object is in variable obj
for (const {data, ...rest} of obj.list) {
    if (rest.name in mappings) {
        Object.assign(mappings[rest.name], data);
    } else {
        mappings[rest.name] = data;
        ordering.push(rest);
    }
}
const newObj = {list: ordering.map(x => ({...x, data: mappings[x.name]}))};

null

const obj = {
    "list": [
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "angular": {
                    "html": ""
                }
            }
        },
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "angular": {
                    "script": ""
                }
            }
        },
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "html": {
                    "html": ""
                }
            }
        },
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "html": {
                    "script": ""
                }
            }
        },
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "react": {
                    "script": ""
                }
            }
        },
        {
            "name": "light_with_header",
            "path": "webapp/master_layouts/sidebar_layouts/",
            "type": "Directory",
            "data": {
                "vue": {
                    "script": ""
                }
            }
        },
    {
        "name": "light_with_header",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "vue": {
                "script": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "angular": {
                "html": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "angular": {
                "script": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "html": {
                "html": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "html": {
                "script": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "react": {
                "script": ""
            }
        }
    },
    {
        "name": "light_with_header_and_icons",
        "path": "webapp/master_layouts/sidebar_layouts/",
        "type": "Directory",
        "data": {
            "vue": {
                "script": ""
            }
        }
    },

    ]
};

const mappings = {};
const ordering = []; // maintain ordering and path/type fields
// assuming your object is in variable obj
for (const {data, ...rest} of obj.list) {
    if (rest.name in mappings) {
        Object.assign(mappings[rest.name], data);
    } else {
        mappings[rest.name] = data;
        ordering.push(rest);
    }
}
const newObj = {list: ordering.map(x => ({...x, data: mappings[x.name]}))};

console.log(newObj);
.as-console-wrapper {min-height: 100%};

匿名用户

下面是另一个解决问题的方案(一个单行)。它与您的需求的不同之处在于,它构建在输入对象的第一个元素上,因此不使用名称“light_with_header_and_icons”而使用名称“light_with_header",

null

const inp={"list": [
  {"name": "light_with_header","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"angular": {"html": ""}}},
  {"name": "light_with_header","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"angular": {"script": ""}}},
  {"name": "light_with_header","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"html": {"html": ""}}},
  {"name": "light_with_header","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"html": {"script": ""}}},
  {"name": "light_with_header","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"react": {"script": ""}}},
  {"name": "light_with_header","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"vue": {"script": ""}}},
  {"name": "light_with_header","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"vue": {"script": ""}}},
  {"name": "light_with_header_and_icons","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"angular": {"html": ""}}},
  {"name": "light_with_header_and_icons","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"angular": {"script": ""}}},
  {"name": "light_with_header_and_icons","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"html": {"html": ""}}},
  {"name": "light_with_header_and_icons","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"html": {"script": ""}}},
  {"name": "light_with_header_and_icons","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"react": {"script": ""}}},
  {"name": "light_with_header_and_icons","path": "webapp/master_layouts/sidebar_layouts/","type": "Directory","data": {"vue": {"script": ""}}}
]}
const res=
inp.list.reduce((a,c)=>(Object.entries(c.data).forEach(([k,v])=>a.data[k]={...a.data[k],...v}),a))
console.log(res)

// alternative version:
const res2=
inp.list.reduce((a,c)=>(Object.entries(c.data).forEach(([k,v])=>a.data[k]={...a.data[k],...v}),a),inp.list[inp.list.length-1])
console.log(res2)