从平面数组javascript生成树

时间:2017-06-13 09:31:49

标签: javascript arrays tree

我有一个数组如下

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: []
                }
            }
        }
    }
}

每当nodes = []时,这意味着它是最后的节点。数组的顺序可以是任何东西,但树应该基于级别构建。

2 个答案:

答案 0 :(得分: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; }




答案 1 :(得分:0)

好吧,根据我们在@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; }