![](/img/trans.png)
[英]how to convert plain array into nested object which is nested into parent object
[英]How to convert a nested array with parent child relationship to a plain array?
我有一个嵌套对象的数组,它们具有如下父子关系:
[
{id: 1, title: 'hello', parent: 0, children: [
{id: 3, title: 'hello', parent: 1, children: [
{id: 4, title: 'hello', parent: 3, children: [
{id: 5, title: 'hello', parent: 4, children: []},
{id: 6, title: 'hello', parent: 4, children: []}
]},
{id: 7, title: 'hello', parent: 3, children: []}
]}
]},
{id: 2, title: 'hello', parent: 0, children: [
{id: 8, title: 'hello', parent: 2, children: []}
]}
]
我需要将其转换为保留父子关系的普通数组,并且按照父子的顺序及其所有子节点首先返回,然后再继续下一个父节点。
[
{id: 1, title: 'hello', parent: 0},
{id: 3, title: 'hello', parent: 1},
{id: 4, title: 'hello', parent: 3},
{id: 5, title: 'hello', parent: 4},
{id: 6, title: 'hello', parent: 4},
{id: 7, title: 'hello', parent: 3},
{id: 2, title: 'hello', parent: 0},
{id: 8, title: 'hello', parent: 2}
]
我能够使用递归 function 进行相反的转换。
但我需要以一种有效的方式做相反的事情。 如示例嵌套数组所示,存在多级嵌套。
编辑:将嵌套数组更新为叶节点有一个空的子数组。
而且,ES5 中的答案会有所帮助。
我只是使用简单的递归 function 将数组 object 制作成普通数组
var arr = [ {id: 1, title: 'hello', parent: 0, children: [ {id: 3, title: 'hello', parent: 1, children: [ {id: 4, title: 'hello', parent: 3, children: [ {id: 5, title: 'hello', parent: 4, children: []}, {id: 6, title: 'hello', parent: 4, children: []} ]}, {id: 7, title: 'hello', parent: 3, children: []} ]} ]}, {id: 2, title: 'hello', parent: 0, children: [ {id: 8, title: 'hello', parent: 2, children: []} ]} ]; var result = []; var convertArrToObj = (arr) => { arr.forEach(e => { if (e.children) { result.push({ id: e.id, title: e.title, parent: e.parent }); convertArrToObj(e.children); } else result.push(e); }); }; convertArrToObj(arr); console.log(result);
在 ES5 中,您还可以使用一些函数式编程方法,并使用[].concat.apply
展平数组:
function flatten(arr) { return [].concat.apply([], arr.map(function (obj) { return [].concat.apply([ { id: obj.id, title: obj.title, parent: obj.parent } ], flatten(obj.children)); })); } let arr = [{id: 1, title: 'hello', parent: 0, children: [{id: 3, title: 'hello', parent: 1, children: [{id: 4, title: 'hello', parent: 3, children: [{id: 5, title: 'hello', parent: 4, children: []},{id: 6, title: 'hello', parent: 4, children: []}]},{id: 7, title: 'hello', parent: 3, children: []}]}]},{id: 2, title: 'hello', parent: 0, children: [{id: 8, title: 'hello', parent: 2, children: []}]}]; console.log(flatten(arr));
在 ES6 中,相同的算法简化为以下内容:
const flatten = arr => arr.flatMap(({children, ...o}) => [o, ...flatten(children)]); let arr = [{id: 1, title: 'hello', parent: 0, children: [{id: 3, title: 'hello', parent: 1, children: [{id: 4, title: 'hello', parent: 3, children: [{id: 5, title: 'hello', parent: 4, children: []},{id: 6, title: 'hello', parent: 4, children: []}]},{id: 7, title: 'hello', parent: 3, children: []}]}]},{id: 2, title: 'hello', parent: 0, children: [{id: 8, title: 'hello', parent: 2, children: []}]}]; console.log(flatten(arr));
使用 ES5 需要更多的代码行,就像你说的那样效率不高。
这是我的 ES5 版本,你应该能注意到性能上的差异
const data = [{id:1,title:'hello',parent:0,children:[{id:3,title:'hello',parent:1,children:[{id:4,title:'hello',parent:3,children:[{id:5,title:'hello',parent:4,children:[]},{id:6,title:'hello',parent:4,children:[]}]},{id:7,title:'hello',parent:3,children:[]}]}]},{id:2,title:'hello',parent:0,children:[{id:8,title:'hello',parent:2,children:[]}]}]; // Recursively function reduceArrayDimension(array) { var level = []; array.forEach(function(item) { level.push({ id: item.id, title: item.title, parent: item.parent }); item.children.forEach(function(child) { reduceArrayDimension([child]).forEach(function(childItem) { level.push(childItem); }); }); }); return level; } console.log(reduceArrayDimension(data));
和 ES6
const data=[{id:1,title:'hello',parent:0,children:[{id:3,title:'hello',parent:1,children:[{id:4,title:'hello',parent:3,children:[{id:5,title:'hello',parent:4,children:[]},{id:6,title:'hello',parent:4,children:[]}]},{id:7,title:'hello',parent:3,children:[]}]}]},{id:2,title:'hello',parent:0,children:[{id:8,title:'hello',parent:2,children:[]}]}]; // Recursively function reduceArrayDimension(array) { const level = []; array.forEach(item => { level.push({id: item.id, title: item.title, parent: item.parent}); if (item.children) level.push(...reduceArrayDimension(item.children)); }); return level; } console.log(reduceArrayDimension(data));
如果数据不是很大,这可能是一种务实的方法
const data = [{ id: 1, title: 'hello', parent: 0, children: [{ id: 3, title: 'hello', parent: 1, children: [{ id: 4, title: 'hello', parent: 3, children: [{ id: 5, title: 'hello', parent: 4 }, { id: 6, title: 'hello', parent: 4, children:[]} ] }, { id: 7, title: 'hello', parent: 3 } ] }] }, { id: 2, title: 'hello', parent: 0, children: [{ id: 8, title: 'hello', parent: 2 }] } ]; const str = JSON.stringify(data).replaceAll('"children":[',"},").replaceAll("]}","").replaceAll(",,",",") // handle empty children.replaceAll(",}","}"); console.log(JSON.parse(str).sort((a,b) => a.id-b.id))
如果数据很大可以考虑使用尾部优化和异步/等待
const arr = [ {id: 1, title: 'hello', parent: 0, children: [ {id: 3, title: 'hello', parent: 1, children: [ {id: 4, title: 'hello', parent: 3, children: [ {id: 5, title: 'hello', parent: 4}, {id: 6, title: 'hello', parent: 4} ]}, {id: 7, title: 'hello', parent: 3} ]} ]}, {id: 2, title: 'hello', parent: 0, children: [ {id: 8, title: 'hello', parent: 2} ]} ]; const convertArr = (arr) => { return arr.reduce((init, cur) => { const plain = init.concat(cur); const children = cur.children; return plain.concat(children && children.length? convertArr(children): []) }, []) } const generateArr = (arr) => { return convertArr(arr).map(v => ({ id: v.id, parent: v.parent, title: v.title })) } console.log('result:', generateArr(arr))
您可以使用生成器 function:
var arr = [ {id: 1, title: 'hello', parent: 0, children: [ {id: 3, title: 'hello', parent: 1, children: [ {id: 4, title: 'hello', parent: 3, children: [ {id: 5, title: 'hello', parent: 4, children: []}, {id: 6, title: 'hello', parent: 4, children: []} ]}, {id: 7, title: 'hello', parent: 3, children: []} ]} ]}, {id: 2, title: 'hello', parent: 0, children: [ {id: 8, title: 'hello', parent: 2, children: []} ]} ]; function* flatten(d){ for (var i of d){ yield {id:i.id, title:i.title, parent:i.parent} yield* flatten(i.children) } } console.log([...flatten(arr)])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.