V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Yukee798
V2EX  ›  问与答

请教一下怎么将路径数组转为树形结构

  •  
  •   Yukee798 · 2022-03-17 11:11:59 +08:00 · 1736 次点击
    这是一个创建于 1016 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在我拿到了类似下面这样的路径数组,里面路径嵌套层级不确定。

    [
      "./home/analysis",
      "./home/boardTodo",
      "./home/dairy",
      "./home",
      "./home/todo",
      "./index",
      "./profile"
    ]
    

    我想把它转换为下面这种树形结构:

    [
      {
        path: "/home",
        children: [
          {
            path: "/home/analysis",
          },
          {
            path: "/home/boardTodo",
          },
          {
            path: "/home/dairy",
          },
          {
            path: "/home/todo",
          }
        ]
      },
      {
        path: "/index",
      },
      {
        path: "/profile",
      }
    ]
    
    12 条回复    2022-03-17 16:09:57 +08:00
    stillsilly
        1
    stillsilly  
       2022-03-17 11:25:33 +08:00
    要什么语言的代码
    wxlwsy
        2
    wxlwsy  
       2022-03-17 11:43:11 +08:00
    这....手写不难吧
    stillsilly
        3
    stillsilly  
       2022-03-17 11:46:14 +08:00   ❤️ 1
    只有两层的话,两个循环就行了
    let arr = [
    "./home/analysis",
    "./home/boardTodo",
    "./home/dairy",
    "./home",
    "./home/todo",
    "./index",
    "./profile"
    ]

    let tree = format(arr)
    console.log(tree)

    function format(arr) {
    let paths = arr.map(path => {
    return path.replace(/^.\//, '').split('/').map(p => '/' + p)
    })

    let result = []
    getLevel1()
    getLevel2()

    function getLevel1() {
    paths.forEach(p => {
    if (p.length === 1) {
    result.push({
    path: p[0],
    children: []
    })
    }
    })
    }

    function getLevel2() {
    paths.forEach(p => {
    let node = result.find(r => r.path === p[0])
    if (p.length !== 1) {
    node.children.push({
    path: '.' + p.join('')
    })
    }
    })
    }

    return result
    }
    stillsilly
        4
    stillsilly  
       2022-03-17 11:47:16 +08:00
    排版好乱,我试一下能不能用 markdown
    ```
    let arr = [
    "./home/analysis",
    "./home/boardTodo",
    "./home/dairy",
    "./home",
    "./home/todo",
    "./index",
    "./profile"
    ]

    let tree = format(arr)
    console.log(tree)

    function format(arr) {
    let paths = arr.map(path => {
    return path.replace(/^.\//, '').split('/').map(p => '/' + p)
    })

    let result = []
    getLevel1()
    getLevel2()

    function getLevel1() {
    paths.forEach(p => {
    if (p.length === 1) {
    result.push({
    path: p[0],
    children: []
    })
    }
    })
    }

    function getLevel2() {
    paths.forEach(p => {
    let node = result.find(r => r.path === p[0])
    if (p.length !== 1) {
    node.children.push({
    path: '.' + p.join('')
    })
    }
    })
    }

    return result
    }


    ```
    stillsilly
        5
    stillsilly  
       2022-03-17 11:48:58 +08:00
    楼主对不起 我污染了这个帖子…… /捂脸逃走
    Yukee798
        6
    Yukee798  
    OP
       2022-03-17 11:53:08 +08:00
    @stillsilly #5 很感谢你的回复,但是里面的路径层级是不确定的,应该会用上递归,但是我没写出来
    Yukee798
        7
    Yukee798  
    OP
       2022-03-17 12:00:42 +08:00
    @stillsilly #5 不好意思 = = 刚刚没有仔细看完代码,我自己改了一下,限制了最大层级,已经能满足我的需求了,很感谢。
    GuuJiang
        8
    GuuJiang  
       2022-03-17 12:04:09 +08:00 via iPhone   ❤️ 3
    Trie ,只不过把标准 Trie 里的单个字母换成路径里的一级
    lyminghao
        9
    lyminghao  
       2022-03-17 13:45:24 +08:00
    建一个 map: path_string -> set
    把每个 path 分级依次插进去,最后统一输出?
    gydi
        10
    gydi  
       2022-03-17 14:15:17 +08:00   ❤️ 1
    murmur
        11
    murmur  
       2022-03-17 14:17:56 +08:00   ❤️ 1
    https://www.npmjs.com/package/path-list-to-tree

    这种东西不需要自己写吧
    Yukee798
        12
    Yukee798  
    OP
       2022-03-17 16:09:57 +08:00
    感谢大家,最后我采用的 Trie 方案,其实写这个东西就是想动态配置一下 React 路由,那个路径数组是用的 require.context 生成的,目前测试了几遍,应该是没问题了,我把完整代码贴出来:
    https://gist.github.com/Yukee-798/3131f9c9b34364e9110f3028abe058aa
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3945 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 05:12 · PVG 13:12 · LAX 21:12 · JFK 00:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.