[英]Merging an array of objects without overwriting
I am currently with some JSON, which has to be structured in a tree-like hierarchy. 我目前使用的是JSON,必须以树状层次结构进行构造。 The depth of the hierarchy varies a lot, and is therefor unknown.
层次的深度变化很大,因此是未知的。
As it is right now, I have achieved to get an array of objects. 到目前为止,我已经实现了获取对象的数组。 Example is below.
示例如下。
[
{
"name": "level1",
"collapsed": true,
"children": [
{
"name": "Level 1 item here",
"id": 360082134191
}
]
},
{
"name": "level1",
"collapsed": true,
"children": [
{
"name": "level2",
"collapsed": true,
"children": [
{
"name": "Level 2 item here",
"id": 360082134751
}
]
}
]
},
{
"name": "level1",
"collapsed": true,
"children": [
{
"name": "Another level 1 item",
"id": 360082262772
}
]
}
]
What I want to achieve is these objects to be merged, without overwriting or replacing anything. 我要实现的是将这些对象合并,而不会覆盖或替换任何内容。 Listed below is an example of how I want the data formatted:
下面列出的是我想要如何格式化数据的示例:
[
{
"name": "level1",
"collapsed": true,
"children": [
{
"name": "level2",
"collapsed": true,
"children": [
{
"name": "Level 2 item here",
"id": 360082134751
}
]
},
{
"name": "Level 1 item here",
"id": 360082134191
},
{
"name": "Another level 1 item",
"id": 360082262772
}
]
}
]
How would I achieve this with JavaScript? 如何使用JavaScript实现此目标? No libraries is preferred, ES6 can be used though.
没有库是首选,但是可以使用ES6。
Edit: It is important that the output is an array, since items without children can appear at the root. 编辑:输出是一个数组很重要,因为没有子项的项可以出现在根目录中。
I am assuming you need a little help on working with the data. 我假设您在处理数据方面需要一点帮助。 There could be multiple ways to achieve this, here is how would I do.
可能有多种方法可以实现这一目标,这就是我的方法。
// data => supplied data
const result = data.reduce ((acc, item) => {
// if acc array already contains an object with same name,
// as current element [item], merfe the children
let existingItem;
// Using a for loop here to create a reference to the
// existing item, so it'd update this item when childrens
// will be merged.
for (let index = 0; index < acc.length; index ++) {
if (acc[index].name === item.name) {
existingItem = acc[index];
break;
}
}
// if existingItem exists, merge children of
// existing item and current item.
// else push it into the accumulator
if (existingItem) {
existingItem.children = existingItem.children.concat(item.children);
} else {
acc.push (item);
}
return acc;
}, []);
I'm assuming you want to group based on the name
property in the level 1 object. 我假设您要基于1级对象中的
name
属性进行分组。 You could do a simple reduce
and Object.values
like this: 您可以执行以下简单的
reduce
和Object.values
:
const input = [{"name":"level1","collapsed":true,"children":[{"name":"Level 1 item here","id":360082134191}]},{"name":"level1","collapsed":true,"children":[{"name":"level2","collapsed":true,"children":[{"name":"Level 2 item here","id":360082134751}]}]},{"name":"level1","collapsed":true,"children":[{"name":"Another level 1 item","id":360082262772}]}] const merged = input.reduce((r,{name, collapsed, children}) =>{ r[name] = r[name] || {name, collapsed, children:[]}; r[name]["children"].push(...children) return r; }, {}) const final = Object.values(merged); console.log(final)
You could do the whole thing in one line: 您可以在一行中完成全部操作:
const input = [{"name":"level1","collapsed":true,"children":[{"name":"Level 1 item here","id":360082134191}]},{"name":"level1","collapsed":true,"children":[{"name":"level2","collapsed":true,"children":[{"name":"Level 2 item here","id":360082134751}]}]},{"name":"level1","collapsed":true,"children":[{"name":"Another level 1 item","id":360082262772}]}] const output = Object.values(input.reduce((r,{name,collapsed,children}) => ( (r[name] = r[name] || {name,collapsed,children: []})["children"].push(...children), r), {})) console.log(output)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.