Javascript 从对象平面阵列构建对象树阵列

Javascript 从对象平面阵列构建对象树阵列,javascript,angular,typescript,Javascript,Angular,Typescript,我想从平面阵列构建树阵列: nodes = [ {id: 1, pid: 0, name: "kpittu"}, {id: 2, pid: 0, name: "news"}, {id: 3, pid: 0, name: "menu"}, {id: 4, pid: 3, name: "node"}, {id: 5, pid: 4, name: "subnode"}, {id: 6, pid: 1, name: "cace"} ]; 这是平面阵列:

我想从平面阵列构建树阵列:

nodes = [
    {id: 1, pid: 0, name: "kpittu"},
    {id: 2, pid: 0, name: "news"},
    {id: 3, pid: 0, name: "menu"},
    {id: 4, pid: 3, name: "node"},
    {id: 5, pid: 4, name: "subnode"},
    {id: 6, pid: 1, name: "cace"}
];
这是平面阵列:

nodes = [
    {id: 1, pid: 0, name: "kpittu"},
    {id: 2, pid: 0, name: "news"},
    {id: 3, pid: 0, name: "menu"},
    {id: 4, pid: 3, name: "node"},
    {id: 5, pid: 4, name: "subnode"},
    {id: 6, pid: 1, name: "cace"}
];
NB:id=节点id;pid=父节点id

我想把它转换成这个数组:

nodes = [{
    id: 1,
    name: 'kpittu',
    childs: [{
        id: 6,
        name: 'cace'
    }]
}, {
    id: 2,
    name: 'news'
}, {
    id: 3,
    name: 'menu',
    childs: [{
        id: 4,
        name: 'node',
        childs: [{
            id: 5,
            name: 'subnode'
        }]
    }]
}];
我尝试使用递归函数来实现预期结果,但我正在寻找更好的方法。感谢您的回复。

使用数组#reduce和助手对象进行迭代:

var节点=[
{id:1,pid:0,名称:“kpittu”},
{id:2,pid:0,名称:“news”},
{id:3,pid:0,名称:“menu”},
{id:4,pid:3,名称:“node”},
{id:5,pid:4,名称:“子节点”},
{id:6,pid:1,名称:“cace”}
];
const helper=nodes.reduce((h,o)=>(h[o.id]=Object.assign({},o),h),Object.create(null));
常量树=节点。减少((t,节点)=>{
const current=helper[node.id];
if(current.pid==0){//如果它没有父推送到根目录
t、 推动(电流);
}否则{
helper[node.pid].children | |(helper[node.pid].children=[])//将子数组添加到父数组(如果它不存在)
helper[node.pid].children.push(当前);//将当前项推送到父-子数组
}
返回t;
}, []);

控制台日志(树)
您可以使用哈希表,将每个循环中的
id
pid
作为连接节点

此建议也适用于未排序的数据

var nodes=[{id:6,pid:1,name:“cace”},{id:1,pid:0,name:“kpittu”},{id:2,pid:0,name:“news”},{id:3,pid:0,name:“menu”},{id:4,pid:3,name:“node”},{id:5,pid:4,name:“subnode”},
树=函数(数据,根){
var r=[],o={};
data.forEach(函数(a){
if(o[a.id]&&o[a.id].儿童){
a、 children=o[a.id]&&o[a.id];
}
o[a.id]=a;
如果(a.pid==根){
r、 推(a);
}否则{
o[a.pid]=o[a.pid]|{};
o[a.pid]。children=o[a.pid]。children | |[];
o[a.pid].children.push(a);
}
});
返回r;
}(节点,0);
控制台日志(树)

。作为控制台包装{max height:100%!important;top:0;}
您还可以使用ES6中引入的Map对象

let nodes = [
  { id: 1, pid: 0, name: "kpittu" },
  { id: 2, pid: 0, name: "news" },
  { id: 3, pid: 0, name: "menu" },
  { id: 4, pid: 3, name: "node" },
  { id: 5, pid: 4, name: "subnode" },
  { id: 6, pid: 1, name: "cace" }
];

function toTree(arr) {
  let arrMap = new Map(arr.map(item => [item.id, item]));
  let tree = [];

  for (let i = 0; i < arr.length; i++) {
    let item = arr[i];

    if (item.pid) {
      let parentItem = arrMap.get(item.pid);

      if (parentItem) {
        let { children } = parentItem;

        if (children) {
          parentItem.children.push(item);
        } else {
          parentItem.children = [item];
        }
      }
    } else {
      tree.push(item);
    }
  }

  return tree;
}

let tree = toTree(nodes);

console.log(tree);

let节点=[
{id:1,pid:0,名称:“kpittu”},
{id:2,pid:0,名称:“news”},
{id:3,pid:0,名称:“menu”},
{id:4,pid:3,名称:“node”},
{id:5,pid:4,名称:“子节点”},
{id:6,pid:1,名称:“cace”}
];
功能树(arr){
让arrMap=newmap(arr.Map(item=>[item.id,item]);
设tree=[];
for(设i=0;i

请同时添加您的函数。建议您,如果您自己没有弄明白这一点,您将无法学习或练习您的递归知识,而不是回答此问题的同事