[英]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.