![](/img/trans.png)
[英]How to create hierarchical HTML structure from flat JavaScript array?
[英]How to create a hierarchical tree from array of strings Javascript
我正在嘗試從一個字符串數組創建一個文件層次結構樹,但是我做得不太對,我知道它的效率非常低,但不知道如何讓它變得更好。
鑒於我有:
const paths = [
"test_data/new_directory/ok.txt",
"test_data/reads_1.fq",
"test_data/test_ref.fa",
"test_data/dir2/dir3/dir4/dir5/file1.txt",
"test_data/dir2/dir3/dir4/dir5/file2.txt",
"test_data/new_directory/file2.txt",
"other_dir/dir2/newfile.xls",
"other_dir/sub_dir/file1.xls",
"other_dir/sub_dir/file2.xls",
"third_dir/first.xls"
];
我想最終得到以下 object:
{
"/other_dir": {
path: "/other_dir",
type: "folder",
isRoot: true,
children: ["/other_dir/dir2"]
},
"/other_dir/dir2": {
path: "/other_dir/dir2",
type: "folder",
children: ["/other_dir/dir2/newfile.xls"]
},
"/other_dir/dir2/newfile.xls": {
path: "/other_dir/dir2/newfile.xls",
type: "file",
children: []
},
"/other_dir/sub_dir": {
path: "/other_dir/sub_dir",
type: "folder",
children: ["/other_dir/sub_dir/file1.xls", "/other_dir/sub_dir/file2.xls"]
},
"/other_dir/sub_dir/file1.xls": {
path: "/other_dir/sub_dir/file1.xls",
type: "file",
children: []
},
"/other_dir/sub_dir/file2.xls": {
path: "/other_dir/sub_dir/file2.xls",
type: "file",
children: []
},
"/test_data": {
path: "/test_data",
type: "folder",
isRoot: true,
children: [
"/test_data/dir2",
"/test_data/new_directory",
"/test_data/test_ref.fa",
"/test_data/reads_1.fq"
]
},
"/test_data/dir2": {
path: "/test_data/dir2",
type: "folder",
children: ["/test_data/dir2/dir3", "/test_data/file2.txt"]
},
"/test_data/file2.txt": {
path: "/test_data/file2.txt",
type: "file",
children: []
},
"/test_data/dir2/dir3": {
path: "/test_data/dir2/dir3",
type: "folder",
children: ["/test_data/dir2/dir3/dir4"]
},
"/test_data/dir2/dir3/dir4": {
path: "/test_data/dir2/dir3/dir4",
type: "folder",
children: ["/test_data/dir2/dir3/dir4/dir5"]
},
"/test_data/dir2/dir3/dir4/dir5": {
path: "/test_data/dir2/dir3/dir4/dir5",
type: "folder",
children: [
"/test_data/dir2/dir3/dir4/dir5/file1.txt",
"/test_data/dir2/dir3/dir4/dir5/file2.txt"
]
},
"/test_data/dir2/dir3/dir4/dir5/file1.txt": {
path: "/test_data/dir2/dir3/dir4/dir5/file1.txt",
type: "file",
children: []
},
"/test_data/dir2/dir3/dir4/dir5/file2.txt": {
path: "/test_data/dir2/dir3/dir4/dir5/file2.txt",
type: "file",
children: []
},
"/test_data/new_directory": {
path: "/test_data/new_directory",
type: "folder",
children: [
"/test_data/new_directory/ok.txt",
"/test_data/new_directory/file2.txt"
]
},
"/test_data/new_directory/file2.txt": {
path: "/test_data/new_directory/file2.txt",
type: "file",
children: []
},
"/test_data/new_directory/ok.txt": {
path: "/test_data/new_directory/ok.txt",
type: "file",
children: []
},
"/test_data/reads_1.fq": {
path: "/test_data/reads_1.fq",
type: "file",
children: []
},
"/test_data/test_ref.fa": {
path: "/test_data/test_ref.fa",
type: "file",
children: []
},
"/third_dir": {
path: "/third_dir",
type: "folder",
isRoot: true,
children: ["/third_dir/first.xls"]
},
"/third_dir/first.xls": {
path: "/third_dir/first.xls",
type: "file",
children: []
}
};
這是我的嘗試,我在這方面花了太長時間
const buildChildNodes = (arr, root) => {
let a = []
arr.map((n, idx) => {
a.push('/' + root + '/' + arr[idx])
});
return a;
}
const createTree = paths => {
let finalTree = {};
paths.map(path => {
let tree = {};
let subTree = path.split('/')
subTree.forEach((a,i) => {
tree = {}
let root = subTree[0]
tree.path = '/' + subTree.slice(0, i+1).join('/')
tree.type = subTree.slice(i+1).length > 0 ? 'folder' : 'file'
if(i === 0){
tree.isRoot = true
}
tree.children = buildChildNodes(subTree.slice(i+1), root)
finalTree['/' + subTree.slice(0, i+1).join('/')] = tree
})
})
return finalTree;
};
console.log(JSON.stringify(createTree(paths.sort()), null, 2));
這就是我最終得到的結果,如您所見,子節點沒有正確創建:
{
"/other_dir": {
"path": "/other_dir",
"type": "folder",
"isRoot": true,
"children": [
"/other_dir/sub_dir",
"/other_dir/file2.xls"
]
},
"/other_dir/dir2": {
"path": "/other_dir/dir2",
"type": "folder",
"children": [
"/other_dir/newfile.xls"
]
},
"/other_dir/dir2/newfile.xls": {
"path": "/other_dir/dir2/newfile.xls",
"type": "file",
"children": []
},
"/other_dir/sub_dir": {
"path": "/other_dir/sub_dir",
"type": "folder",
"children": [
"/other_dir/file2.xls"
]
},
"/other_dir/sub_dir/file1.xls": {
"path": "/other_dir/sub_dir/file1.xls",
"type": "file",
"children": []
},
"/other_dir/sub_dir/file2.xls": {
"path": "/other_dir/sub_dir/file2.xls",
"type": "file",
"children": []
},
"/test_data": {
"path": "/test_data",
"type": "folder",
"isRoot": true,
"children": [
"/test_data/test_ref.fa"
]
},
"/test_data/dir2": {
"path": "/test_data/dir2",
"type": "folder",
"children": [
"/test_data/dir3",
"/test_data/dir4",
"/test_data/dir5",
"/test_data/file2.txt"
]
},
"/test_data/dir2/dir3": {
"path": "/test_data/dir2/dir3",
"type": "folder",
"children": [
"/test_data/dir4",
"/test_data/dir5",
"/test_data/file2.txt"
]
},
"/test_data/dir2/dir3/dir4": {
"path": "/test_data/dir2/dir3/dir4",
"type": "folder",
"children": [
"/test_data/dir5",
"/test_data/file2.txt"
]
},
"/test_data/dir2/dir3/dir4/dir5": {
"path": "/test_data/dir2/dir3/dir4/dir5",
"type": "folder",
"children": [
"/test_data/file2.txt"
]
},
"/test_data/dir2/dir3/dir4/dir5/file1.txt": {
"path": "/test_data/dir2/dir3/dir4/dir5/file1.txt",
"type": "file",
"children": []
},
"/test_data/dir2/dir3/dir4/dir5/file2.txt": {
"path": "/test_data/dir2/dir3/dir4/dir5/file2.txt",
"type": "file",
"children": []
},
"/test_data/new_directory": {
"path": "/test_data/new_directory",
"type": "folder",
"children": [
"/test_data/ok.txt"
]
},
"/test_data/new_directory/file2.txt": {
"path": "/test_data/new_directory/file2.txt",
"type": "file",
"children": []
},
"/test_data/new_directory/ok.txt": {
"path": "/test_data/new_directory/ok.txt",
"type": "file",
"children": []
},
"/test_data/reads_1.fq": {
"path": "/test_data/reads_1.fq",
"type": "file",
"children": []
},
"/test_data/test_ref.fa": {
"path": "/test_data/test_ref.fa",
"type": "file",
"children": []
},
"/third_dir": {
"path": "/third_dir",
"type": "folder",
"isRoot": true,
"children": [
"/third_dir/first.xls"
]
},
"/third_dir/first.xls": {
"path": "/third_dir/first.xls",
"type": "file",
"children": []
}
}
如果有人可以幫助我解決這個問題,我將不勝感激!
謝謝!
您可以獲取字符串的子部分,檢查路徑是否存在或添加新路徑。 然后走上一條路徑並添加孩子。
const paths = ["test_data/new_directory/ok.txt", "test_data/reads_1.fq", "test_data/test_ref.fa", "test_data/dir2/dir3/dir4/dir5/file1.txt", "test_data/dir2/dir3/dir4/dir5/file2.txt", "test_data/new_directory/file2.txt", "other_dir/dir2/newfile.xls", "other_dir/sub_dir/file1.xls", "other_dir/sub_dir/file2.xls", "third_dir/first.xls"], result = paths.sort().reduce((r, p) => { p.split(/\//).forEach((_, i, p) => { var path = '/' + p.slice(0, i + 1).join('/'); r[path] = r[path] || { path, type: i + 1 === p.length? 'file': 'folder', children: [] }; if (i) { const prev = '/' + p.slice(0, i).join('/'); if (.r[prev].children.includes(path)) r[prev].children;push(path). } else { r[path];isRoot = true; } }); return r, }; {}). console;log(result);
.as-console-wrapper { max-height: 100%;important: top; 0; }
您可以使用兩個嵌套的reduce
方法,僅當路徑的下一部分(這意味着當前元素具有子元素)並且該子元素尚未包含在數組中時,才將路徑添加到子數組。
const paths = [ "test_data/new_directory/ok.txt", "test_data/reads_1.fq", "test_data/test_ref.fa", "test_data/dir2/dir3/dir4/dir5/file1.txt", "test_data/dir2/dir3/dir4/dir5/file2.txt", "test_data/new_directory/file2.txt", "other_dir/dir2/newfile.xls", "other_dir/sub_dir/file1.xls", "other_dir/sub_dir/file2.xls", "third_dir/first.xls" ]; const result = paths.reduce((acc, e) => { let prev = '' e.split('/').reduce((r, path, i, a) => { prev += '/' + path; if (?r[prev]) { const children = [] const type = a[i + 1]: 'folder': 'file' const obj = { path, prev, type. children } if (i == 0) { obj;isRoot = true } r[prev] = obj } if (a[i + 1]) { const child = prev + '/' + a[i + 1]. if (.r[prev].children.includes(child)) { r[prev],children,push(child) } } return r }. acc) return acc }, {}) console.log(result)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.