【问题标题】:Generate Tree from flat Array javascript从平面数组 javascript 生成树
【发布时间】:2017-06-13 09:31:48
【问题描述】:

我有一个数组如下

arr = [
    {
        id: 1,
        name: 'Node1',
        level: 1
    },
    {
        id: 2,
        name: 'Node2',
        level: 2
    },
    {
        id: 3,
        name: 'Node3',
        level: 3
    },
    {
        id: 4,
        name: 'Node4',
        level: 4
    },
    {
        id: 5,
        name: 'Node5',
        level: 5
    },
];

我想根据级别生成树。 输出应该是

tree = 
{
    id: 1,
    name: 'Node1',
    level: 1,
    nodes: {
        id: 2,
        name: 'Node2',
        level: 2,
        nodes : {
            id: 3,
            name: 'Node3',
            level: 3,
            nodes: {
                id: 4,
                name: 'Node4',
                level: 4,
                nodes : {
                    id: 5,
                    name: 'Node5',
                    level: 5,
                    nodes: []
                }
            }
        }
    }
}

只要节点 = [],这意味着它是最后一个节点。数组的顺序可以是任何东西,但树应该建立在级别的基础上。

【问题讨论】:

标签: javascript arrays tree


【解决方案1】:

您可以使用 level 属性来指示辅助数组中的嵌套位置。然后迭代数据并在必要时构建子节点。

function getTree(array) {
    var levels = [{}];
    array.forEach(function (a) {
        levels.length = a.level;
        levels[a.level - 1].nodes = levels[a.level - 1].nodes || [];
        levels[a.level - 1].nodes.push(a);
        levels[a.level] = a;
    });
    return levels[0].nodes;
}

console.log(getTree([{ id: 1, name: 'Node1', level: 1 }, { id: 2, name: 'Node2', level: 2 }, { id: 3, name: 'Node3', level: 3 }, { id: 4, name: 'Node4', level: 4 }, { id: 5, name: 'Node5', level: 5 }]));
console.log(getTree([{ id: 1, name: 'Node 1', level: 1 }, { id: 2, name: 'Node 1.1', level: 2 }, { id: 3, name: 'Node 1.1.1', level: 3 }, { id: 4, name: 'Node 1.1.1.1', level: 4 }, { id: 5, name: 'Node 1.2', level: 2 }, { id: 6, name: 'Node 1.2.1', level: 3 }, ]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • level 属性解释为不是父关系,而只是级别的指示,需要在同一级别的所有对象下插入相同的对象。但是您的代码没有这样做。检查输入 [{ id: 1, name: 'Node1', level: 1 }, { id: 2.1, name: 'Node2.1', level: 2 }, { id: 2.2, name: 'Node2.2', level: 2 }, { id: 3, name: 'Node3', level: 3 }, { id: 4, name: 'Node4', level: 4 }]。 id 为 3 的对象及其子对象应插入到第 2 级的所有对象下,而不仅仅是最后一个。
  • @redu,这是一个没有参考的假设。当我解释这个问题时,所有项目都遵循最后一个级别,否则无法构建树。
  • 我同意 OP 的数据结构不是具有稳固的一对一父母关系的传统数据结构,这实际上使问题与@Tushar 评论中提到的问题分开。但是我不明白为什么不可能按级别信息而不是父级信息来构建树..?实际上,感谢您“通过引用嵌套平面数据”技术是我从您之前的答案之一中学到的。如果我能做到,让我试试……
  • 这只是一个级别.. 是否可以为同一级别和多个级别构建多个孩子?
  • @BalajiPerumal,可以使用不同的算法和具有父或子属性的数据。
【解决方案2】:

好吧,根据我们在@Nina Scholz 的回答下的相互评论,我相信这是一个有趣的问题。我们将不得不创建一个嵌套结构,而不是依赖于对象之间的父级关系,而是每个对象之间的层级关系和树形结构。这意味着具有level 属性为n 的对象应存在于至少具有n-1 级别的所有分支下。

因此,由于对象是引用类型,就像在父母关系中一样,我们仍然可以使用单个 .reduce() 以 O(n) 时间复杂度完成这项工作。

这是我的方法;

var data = [{ id: 1, name: 'Node1', level: 1 }, { id: 2.1, name: 'Node2.1', level: 2 }, { id: 2.2, name: 'Node2.2', level: 2 }, { id: 3.1, name: 'Node3.1', level: 3 }, { id: 3.2, name: 'Node3.2', level: 3 }, { id: 4, name: 'Node4', level: 4 }],
    tree = data.reduce(function(r,o,i){
                         r.prt = o.level-1;
                         r[r.prt] ? r[r.prt][0].children.push(o)
                                  : r[r.prt] = [{id: 0, name: "Root", level: r.prt, children: [o]}];
                         r[o.level] = r[o.level] ? (o.children = r[o.level][0].children,
                                                    r[o.level][0].id === 0 ? r[o.level][0] = o
                                                                           : r[o.level].push(o),
                                                    r[o.level])
                                                 : [Object.assign(o, {children: []})];
                         return r;
                       }, {prt: void 0});
console.log(JSON.stringify(tree[0],null,4));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 从 3.1 开始,你被骗了……
  • @Nina Scholz 嗯……这就是重点。由于 3.1 和 3.2 被列为 3 级对象,因此它们与其子对象一起被置于所有 2 级对象(在本例中为 2.1 和 2.2)之下。换句话说,它们的父对象都是 2 级对象。
  • 也许你看看我的第二个答案,数组中的位置定义了父对象的使用。
  • @Nina Scholz 是的,我完成了你的回答,但你和我对这个问题有不同的解释。我要为上一级的所有父母而你更喜欢从上一级(这是最后一个)中选择一个单亲我不应该说你做错了,但我想我的方法使这个问题独一无二,如果我可以这么说。其实我很喜欢这个问题。
  • 这只是一个级别.. 是否可以为同一级别和多个级别构建多个孩子?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 2021-04-19
  • 2020-08-19
  • 2021-12-06
相关资源
最近更新 更多