如何将数组数组转换为深嵌套树视图

时间:2018-01-26 18:52:00

标签: javascript algorithm tree grouping

我正在通过将路径数组转换为树视图数据结构来构建树视图。这就是我想要做的事情:

// routes are sorted.
let routes = [
    ['top', '1.jpg'],
    ['top', '2.jpg'],
    ['top', 'unsplash', 'photo.jpg'],
    ['top', 'unsplash', 'photo2.jpg'],
    ['top', 'foo', '2.jpg'],
    ['top', 'foo', 'bar', '1.jpg'],
    ['top', 'foo', 'bar', '2.jpg']
];

into 

let treeview = {
  name: 'top', child: [
    {name: '1.jpg', child: []},
    {name: '2.jpg', child: []},
    {name: 'unsplash', child: [
        {name: 'photo.jpg', child: []},
        {name: 'photo2.jpg', child: []}
    ]},
    {name: 'foo', child: [
        {name: '2.jpg', child: []},
        {name: 'bar', child: [
            {name: '1.jpg', child: []},
            {name: '2.jpg', child: []}
        ]}
    ]}
]}

现在我已成功通过此方法转换单个数组项,但无法对多个数组执行此操作。另请注意,嵌套的treeview不包含重复项。

function nest(arr) {
    let out = [];
    arr.map(it => {
        if(out.length === 0) out = {name: it, child: []}
        else {
            out = {name: it, child: [out]}
        }
    });
    return out;
}

1 个答案:

答案 0 :(得分:6)

您可以使用嵌套哈希表来访问路由,并将数组作为结果集。如果只有一个根元素,则可以获取结果数组的第一个元素。

var routes = [['top', '1.jpg'], ['top', '2.jpg'], ['top', 'unsplash', 'photo.jpg'], ['top', 'unsplash', 'photo2.jpg'], ['top', 'foo', '2.jpg'], ['top', 'foo', 'bar', '1.jpg'], ['top', 'foo', 'bar', '2.jpg']],
    result = [],
    temp = { _: result };

routes.forEach(function (path) {
    path.reduce(function (level, key) {
        if (!level[key]) {
            level[key] = { _: [] };
            level._.push({ name: key, children: level[key]._ });
        }
        return level[key];
    }, temp);
});

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

ES6没有临时对象,但是带有路径名的命名对象的搜索。

var routes = [['top', '1.jpg'], ['top', '2.jpg'], ['top', 'unsplash', 'photo.jpg'], ['top', 'unsplash', 'photo2.jpg'], ['top', 'foo', '2.jpg'], ['top', 'foo', 'bar', '1.jpg'], ['top', 'foo', 'bar', '2.jpg']],
    result = [];

routes.forEach(function (path) {
    path.reduce(function (level, key) {
        var temp = level.find(({ name }) => key === name);
        if (!temp) {
            temp = { name: key, children: [] };
            level.push(temp);
        }
        return temp.children;
    }, result);
});

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