You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript实现:将路径列表转为类字典嵌套对象的问题

问题:将路径列表转换为嵌套对象结构

我有如下路径列表:

[
"posts/index/cms.md",
"posts/index/test/sidegenerator.md",
"posts/ssg/gatsby.md",
"posts/ssg/hugo.md",
"posts/ssg/generator/rt/gen.txt",
"example/test.md"
]

想要转换为嵌套对象结构:

{
    "posts": {
        "index": {
            "cms.md": null,
            "test": {
                "sidegenerator.md": null
            }
        },
        "ssg": {
            "gatsby.md": null,
            "hugo.md": null,
            "generator": {
                "rt": {
                    "gen.txt": null
                }
            }
        }
    },
    "example": {
        "test.md": null
    }
}

我有Python背景,知道JavaScript中没有字典,只有具备类字典功能的Object(键值对形式)。自己编写了递归函数,但遇到对象引用问题,无法给已有对象添加新键,现有代码及输出如下:

现有代码

辅助函数

function create_dict_outof_list(index, rest_of_list){
  if (index == rest_of_list.length-1){
    return rest_of_list[index]
  }else {
    let new_dict = {}
    new_dict[rest_of_list[index]] = create_dict_outof_list(index+1, rest_of_list)
    return new_dict
  }
  
}

递归生成函数

function recursive_dict_generator(data_dict, index, list){

  console.log("Dict: ", list[index] in data_dict)
  if (index < list.length-1){
    if (list[index] in data_dict){
      return data_dict[list[index]] = recursive_dict_generator(data_dict[list[index]], index+1, list)

    } else {
      return data_dict[list[index]] = create_dict_outof_list(0, list.slice(index))
    }
  } else {
    if (list[index] in data_dict){

      return data_dict

    } else {
      return list[index]
    }
  }

}

测试主函数

function main(){

  let data_dict = {}
  let new_dict = {}
  new_dict = recursive_dict_generator(data_dict, 0, ["posts","index", "test", "sidegenerator.md"])
  console.log("test 1: ", data_dict)
  console.log("test 1.5", new_dict)
  
  recursive_dict_generator(data_dict, 0, ["posts","ssg", "generator", "rt", "test.md"])
  console.log("test 2: ", data_dict)

}

控制台输出

test 1:  { posts: { posts: { index: [Object] } } }
test 1.5 { posts: { index: { test: 'sidegenerator.md' } } }
test 2:  { posts: { ssg: { generator: [Object] } } }

解决方案

你的代码核心问题有两个:

  1. create_dict_outof_list调用时传入list.slice(index)后从索引0开始递归,导致重复创建外层键(比如第一次测试里的posts被重复嵌套)。
  2. 处理文件片段时,直接返回文件名而非给当前对象赋值null,且已有键存在时的逻辑不符合需求。

可以简化逻辑,用单循环+对象引用追踪就能完成,无需拆分多个递归函数:

function buildNestedStructure(paths) {
  const result = {};
  paths.forEach(path => {
    const segments = path.split('/');
    let current = result;
    for (let i = 0; i < segments.length; i++) {
      const segment = segments[i];
      // 最后一段是文件,直接赋值为null
      if (i === segments.length - 1) {
        current[segment] = null;
      } else {
        // 当前层级无该键则创建空对象
        if (!current[segment]) {
          current[segment] = {};
        }
        // 切换到下一层级对象
        current = current[segment];
      }
    }
  });
  return result;
}

// 测试用例
const paths = [
  "posts/index/cms.md",
  "posts/index/test/sidegenerator.md",
  "posts/ssg/gatsby.md",
  "posts/ssg/hugo.md",
  "posts/ssg/generator/rt/gen.txt",
  "example/test.md"
];

console.log(JSON.stringify(buildNestedStructure(paths), null, 2));

代码说明

  • 遍历每个路径,用split('/')拆分成路径片段数组。
  • 用current变量追踪当前操作的层级对象,初始指向根对象result。
  • 循环处理每个片段:
    • 如果是最后一个片段(文件名),直接给当前对象的对应键赋值null。
    • 如果是目录片段,检查当前对象是否已有该键,没有则创建空对象,然后将current切换到这个子对象,继续处理下一层。

这种方式能正确复用已有对象的引用,不会覆盖或重复创建键,最终生成目标嵌套结构。

内容的提问来源于stack exchange,提问作者Luca Moser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 19:15:31