Javascript 如何将具有父子关系的嵌套数组转换为普通数组?

Javascript 如何将具有父子关系的嵌套数组转换为普通数组?,javascript,arrays,algorithm,tree,depth-first-search,Javascript,Arrays,Algorithm,Tree,Depth First Search,我有一个数组,其中嵌套的对象具有父子关系,如下所示: [ {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: 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}
]
我可以用递归函数进行相反的转换

但我需要以一种有效的方式做相反的事情。如示例嵌套数组所示,存在多级嵌套

编辑:已更新嵌套数组,使叶节点的子数组为空


此外,ES5中的答案也会有所帮助。

如果数据不是很大,这可能是一种实用的方法

const data=[{id:1,title:'hello',父:0,子:[{id:3,title:'hello',父:1,子:[{id:4,title:'hello',父:3,子:[{id:5,title:'hello',父:4,子:[]},{id:7,title:'hello',父:3}]},{id:2,title:'hello',父:0,子:[{id:8,标题:'hello',父项:2}]};
const str=JSON.stringify(数据)
.replaceAll(““子项”:[”,“},”)
.replaceAll(“]}”,“”)
.replaceAll(“,”,“,”)//处理空子级
.replaceAll(“,}”,“}”);

控制台.log(JSON.PARSE(STR).排序((A,B)= .A.ID-B.ID))

如果数据大,可以考虑使用尾部优化和异步/等待< /P>

const arr=[
{id:1,标题:'hello',父项:0,子项:[
{id:3,标题:“你好”,家长:1,孩子:[
{id:4,标题:“你好”,家长:3,孩子:[
{id:5,标题:“你好”,家长:4},
{id:6,标题:'hello',家长:4}
]},
{id:7,标题:'hello',家长:3}
]}
]},
{id:2,标题:'hello',父项:0,子项:[
{id:8,标题:'hello',家长:2}
]}
];
const convertArr=(arr)=>{
返回arr.reduce((初始,当前)=>{
常量平原=初始浓度(当前);
const children=cur.children;
返回plain.concat(children&&childrence.length?convertArr(children):[])
}, [])
}
const generatarr=(arr)=>{
返回convertArr(arr).map(v=>({
id:v.id,
家长:v.parent,
标题:v.标题
}))
}

console.log('result:',generatearl(arr))
使用ES5需要更多的代码行,正如您所说的,效率不高

这是我的ES5版本,您应该能够注意到性能上的差异

const data=[{id:1,title:'hello',parent:0,children:[{id:3,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 children:[]}},{id:2,title:'hello',parent:0,children parent:[]}];
//递归地
函数reduceArrayDimension(数组){
风险值水平=[];
array.forEach(函数(项){
水平推({
id:item.id,
标题:item.title,
父项:item.parent
});
item.children.forEach(函数(子函数){
reduceArrayDimension([child]).forEach(函数(childItem){
水平推送(子项);
});
});
});
回报水平;
}

console.log(reduceArrayDimension(数据))我只是使用一个简单的递归函数将数组对象转换成普通数组

var arr=[{id:1,title:'hello',父:0,子:[{id:3,title:'hello',父:1,子:[{id:4,title:'hello',父:3,子:[]},{id:6,title:'hello',父:4,子:[]},{id:7,title:'hello',父:3,子:[]},{id:2,标题:'hello',父项:0,子项:[{id:8,标题:'hello',父项:2,子项:[]}];
var结果=[];
var convertArrToObj=(arr)=>{
arr.forEach(e=>{
如果(如儿童){
结果:推({
id:e.id,
标题:e.标题,
家长:e.parent
});
convertArrToObj(e.儿童);
}否则结果。推(e);
});
};
转换器arrtoobj(arr);

console.log(result);
在ES5中,您还可以使用一些函数式编程方法,并使用
[].concat.apply展平数组:

函数展平(arr){
返回[].concat.apply([],arr.map(函数(obj)){
返回[]。concat.apply([
{id:obj.id,title:obj.title,父对象:obj.parent}
]扁平化(对象儿童);
}));
}
让arr=[{id:1,title:'hello',parent:0,children:[{id:3,title:'hello',parent:1,children:[{id:4,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,标题:'hello',父:2,子:[]}];

console.log(展平(arr));
您可以使用生成器功能:

var arr=[{id:1,title:'hello',父:0,子:[{id:3,title:'hello',父:1,子:[{id:4,title:'hello',父:3,子:[]},{id:6,title:'hello',父:4,子:[]},{id:7,title:'hello',父:3,子:[]},{id:2,标题:'hello',父项:0,子项:[{id:8,标题:'hello',父项:2,子项:[]}];
函数*展平(d){
用于(变量i/d){
收益{id:i.id,title:i.title,parent:i.parent}
产量*扁平化(即儿童)
}
}

console.log([…展平(arr)])
更新了问题,将叶节点包含一个空数组。这会为更新后的场景引发一个错误。我可以解析对象并删除一个空的子数组以使其工作。@Priyankerlao更新处理空的子数组我永远不想指望这样的东西,但我对它的工作印象深刻!很好,很简单。谢谢。我通过深入克隆“e”对象并从中删除children属性对该解决方案进行了一些更新。这只是以防万一