How to transform array of strings into specific tree structure in Javascript

北战南征 提交于 2021-02-18 18:49:59

问题


I get a list of file paths from the backend, it represents a folder structure and looks like this:

paths = ["path/to/file1.doc", "path/to/file2.doc", "foo/bar.doc]

The lengths of the paths are arbitrary. In order to use a file tree component (angular2-tree-component) I need to transform this data into the following format:

nodes = [
    {
        "name": "path",
        "children": [
            {
                "name": "to",
                "children": [
                    {"name": "file1.doc"},
                    {"name": "file2.doc"}
                ]
            }
        ]
    },
    {
        "name": "foo",
        "children": [
            {"name": "bar.doc"}
        ]
    }
]

I think the most efficient way to transform the data is to

  1. Map the array with the files mirroring a tree structure first and then to
  2. Iterate over every key in order to finalise the "children/parent" relations.

Step one:

transformToTree(data) {
    const tree = {};
    function addPathsToTree(paths) {
        let map = tree
        paths.forEach(function(item) {
            map[item] = map[item] || {};
            map = map[item];
        });
    }
    data.forEach(function(path) {
        let pathPart = path.split('/');
        addPathsToTree(pathPart);
    });
    return pathTree;
}

When passing "nodes" into the transformToTree function (transformToTree(nodes)), I get the following result:

{
    "path": {
        "to": {
            "file1.doc": {},
            "file2.doc": {}
        }
    },
    "foo": {
        "bar": {}
    }
}

I don't know how to proceed from here = how to iterate over all the keys and values while building the final array in the required structure.

There are a few examples like this or that on SO, but I was not able to understand how I could adapt them to my needs.


回答1:


I would go with two nested loops, one for pathes and one for the splitted names and find the name or create new objects.

var paths = ["path/to/file1.doc", "path/to/file2.doc", "foo/bar.doc"],
    result = [];
    
paths.reduce((r, path) => {
    path.split('/').reduce((o, name) => {
        var temp = (o.children = o.children || []).find(q => q.name === name);
        if (!temp) o.children.push(temp = { name });
        return temp;
    }, r);
    return r;
}, { children: result });

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


来源:https://stackoverflow.com/questions/59049635/how-to-transform-array-of-strings-into-specific-tree-structure-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!