簡體   English   中英

如何從字符串數組 Javascript 創建層次樹

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM