首页 > 解决方案 > 从包含文件路径的字符串列表创建树 - javascript

问题描述

假设我有以下数组:

[
    "About.vue", 
    "Categories/Index.vue", 
    "Categories/Demo.vue", 
    "Categories/Flavors.vue"
]

我们使用Index.vue每个子文件夹中的 来充当该文件夹的父文件夹。这意味着上面看起来像:

[
  { 
    name: "About", 
    children: [] 
  }, 
  { 
    name: "Categories", 
    children: 
    [
      {
        name: "Index.vue", 
        children: [] 
      },
      {
        name: "Demo.vue", 
        children: [] 
      },
      { 
        name: "Flavors.vue", 
        children: [] 
      }
    ]
  }
]

通过使用以下教程,我能够让它稍微工作:https ://joelgriffith.net/array-reduce-is-pretty-neat/

然而,它是一个根对象,每个文件都有一个属性,而不是一个数组,每个文件都有一个对象。

以下代码产生预期的输出:

let paths = [
    "About.vue", 
    "Categories/Index.vue", 
    "Categories/Demo.vue", 
    "Categories/Flavors.vue"
];


let helper = {
  index: -1,
  name: ""
};

function treeify(files) {
  var fileTree = [];

  function mergePathsIntoFileTree(prevDir, currDir, i, filePath) {

    helper.name = currDir;
    helper.index = i;
      
    if (helper.index == 0) {
      let index = prevDir.findIndex(x => x.name == helper.name);
      if (index < 0) {
        prevDir.push({
          name: helper.name,
          children: []
        });
      }
      
      return prevDir;
    }
    
    if (helper.index >= 0) {
      let obj = {
        name: currDir,
        children: []
      };
      
      prevDir[helper.index].children.push(obj);
      helper.index = i;
      helper.name = currDir;
    }
   
  }

  function parseFilePath(filePath) {
    var fileLocation = filePath.split('/');

    // If file is in root directory, eg 'index.js'
    if (fileLocation.length === 1) {
      fileTree[0] = {
        name: fileLocation[0],
        children: []
      };
    } else {
      fileLocation.reduce(mergePathsIntoFileTree, fileTree);
    }
  }

  files.forEach(parseFilePath);

  return fileTree;
}

console.log(treeify(paths));

但是,它在以下输入时失败:

let paths = [
    "About.vue", 
    "Categories/Index.vue", 
    "Categories/Demo.vue", 
    "Categories/Flavors.vue",
    "Categories/Types/Index.vue",
    "Categories/Types/Other.vue"
];

有谁知道让它适用于进一步嵌套的路径列表的解决方案?

标签: javascriptpathtree

解决方案


您可以使用方法创建此结构forEach,循环每个路径并将其拆分为数组 on /,然后您也可以使用reduce方法创建嵌套对象。

let paths = ["About.vue","Categories/Index.vue","Categories/Demo.vue","Categories/Flavors.vue","Categories/Types/Index.vue","Categories/Types/Other.vue"];

let result = [];
let level = {result};

paths.forEach(path => {
  path.split('/').reduce((r, name, i, a) => {
    if(!r[name]) {
      r[name] = {result: []};
      r.result.push({name, children: r[name].result})
    }
    
    return r[name];
  }, level)
})

console.log(result)


推荐阅读