簡體   English   中英

如何將具有父子關系的嵌套數組轉換為普通數組?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM