繁体   English   中英

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

[英]Merge nested JavaScript objects based on same nested key

我一直在尝试打开以下输入:

{
    "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": ""
            }
        }
    },

    ]
}

对于 output:

{
    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])
       }
    })
}

如何从提供的输入中获取演示的 output?

编辑

这是完全满足上述要求的更新版本:

 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 =Object.values(inp.list.reduce((a,c)=>{ // Object.values: only return the different *values* of the collection let nam=c.name+c.path+c.type; // collect "similar" objects together let curr=a[nam]=a[nam]||{...c}; // create or refer to a collection element Object.entries(c.data).forEach(([k,v])=>curr.data[k]={...curr.data[k],...v}) return a},{})); console.log(res)

之前的版本...
这是您问题的另一种解决方案(单线)。 它与您的要求不同,它建立在输入 object 的第一个元素上,因此不包含名称“light_with_header_and_icons”而不是“light_with_header”,

 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)

我的“替代”版本返回一个 output object ,它建立在inp.list最后一个元素上。

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

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]}))};

 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%};

这是使用find()检查现有条目的简单reduce()

 const input = { "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 output = {}; output.list = input.list.reduce((a, o) => { const p = a.find(({ name }) => name === o.name); if (p) { Object.entries(o.data).forEach(([k, v]) => p.data[k] = {...p.data[k]?? {}, ...v } ); } else { a.push({...o }) } return a; }, []); console.log(output)

我找到了我需要的解决方案。 真的谢谢大家的帮助。 我修改了cars10m。 我创建了一个新列表和 append 全部到它。 我的未来代码..

let myList = []
list.reduce((a,c)=>{
    if(a.name !== c.name){
        myList.push(c)
        return c
    }else{
        return (Object.entries(c.data).forEach(([k,v])=>a.data[k]={...a.data[k],...v}),a)
    }
},list[list.length-1])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM