我如何通过它们的parentId和Id在Javascript中从这个平面数组构建一个树数组。

时间:2018-03-20 20:02:08

标签: javascript arrays object tree

我有一个像这样的平面阵列,我应该为它构建一个平面阵列。如果pid不为null,则该对象将是其父对象的子属性。我该怎么做?

    var a = [
        {id: 1, pid: null}, 
        {id: 2, pid: 1}, 
        {id: 3, pid: 1}, 
        {id: 4, pid: 3}, 
        {id: 5, pid: 3}
     ];

期待输出:

     var result = [{id: 1, children: [
        {id: 2, children: []},
        {id: 3, children: [{id: 4}, {id: 5}]}
    ]}]

4 个答案:

答案 0 :(得分:1)

您可以使用reduce()方法创建递归函数。

var a = [{id: 1, pid: null}, {id: 2, pid: 1}, {id: 3, pid: 1}, {id: 4, pid: 3}, {id: 5, pid: 3}];

function tree(data, parent) {
  return data.reduce((r, {id,pid}) => {
    if (parent == pid) {
      const obj = {id}
      const children = tree(data, id);
      if (children.length) obj.children = children;
      r.push(obj)
    }
    return r;
  }, [])
}

const result = tree(a, null);
console.log(result);

答案 1 :(得分:1)

您可以使用单循环方法,也适用于未排序的数组。

var a = [{ id: 1, pid: null }, { id: 2, pid: 1 }, { id: 3, pid: 1 }, { id: 4, pid: 3 }, { id: 5, pid: 3 }],
    tree = function (data, root) {
        return data.reduce(function (o, { id, pid }) {
            o[id] = o[id] || { id };
            o[pid] = o[pid] || { id: pid };
            o[pid].children = o[pid].children || [];
            o[pid].children.push(o[id]);
            return o;
        }, {})[root].children;
    }(a, null);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

这两个使用reduce的答案都很棒,一个小问题就是有多遍,IOW:如果树很大,那么就会有很多线性搜索。

对此的一个解决方案是首先构建一个地图,然后展平地图.. mmm,实际上是扁平的,这里可能是错误的单词,也许扩展.. :)但是你明白了......

以下是一个例子。



const a = [
    {id: 1, pid: null}, 
    {id: 2, pid: 1}, 
    {id: 3, pid: 1}, 
    {id: 4, pid: 3}, 
    {id: 5, pid: 3}
 ];
 
 
function flatern(map, parent) {
  const g = map.get(parent);
  const ret = [];
  if (g) {
    for (const id of g) {
      const k = {id};
      ret.push(k);
      const sub = flatern(map, id);
      if (sub) k.children = sub;
    }
    return ret;
  }
  return null;
}
     
function tree(a) {
  const m = new Map();
  a.forEach((i) => {
    const g = m.get(i.pid);
    if (!g) {
      m.set(i.pid, [i.id]);
    } else {
      g.push(i.id);
    }
  });
  return flatern(m, null);
}

console.log(tree(a));

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 3 :(得分:0)

    var a = [
        {id: 1, pid: null}, 
        {id: 2, pid: 1}, 
        {id: 3, pid: 1}, 
        {id: 4, pid: 3}, 
        {id: 5, pid: 3}
    ];

    function processToTree(data) {
        const map = {};
        data.forEach(item => {
            map[item.id] = item;
            item.children = [];
        });

        const roots = [];
        data.forEach(item => {
            const parent = map[item.pid];
            if (parent) {
                parent.children.push(item);
            }
            else {
                roots.push(item);
            }
        });
        return roots;
    }

今天学会了这种方法,我认为这是最好的