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

JavaScript构建目录树时迭代前清空Array的最优位置

编辑:我此前尝试去重的思路走了弯路,实际需求是先清空数组再做后续处理。

如下是示例代码,我想要找到每次迭代前清空parent.subdirectories数组的最优位置。

const mainArray = [{Id:1,Name:"test",SubDirectoryCount:10,Files:[]}];
const directories = [{Id:56,Name:"Client 2",SubDirectoryCount:1,ParentId:1,Files:[]},{Id:53,Name:"Client 3",SubDirectoryCount:1,ParentId:1,Files:[]},{Id:50,Name:"Client 4",SubDirectoryCount:1,ParentId:1,Files:[]},{Id:48,Name:"Client 5",SubDirectoryCount:1,ParentId:53,Files:[]},{Id:47,Name:"Client 5",SubDirectoryCount:1,ParentId:53,Files:[]},{Id:49,Name:"Client 5",SubDirectoryCount:1,ParentId:53,Files:[]}];

// create flat list
const tmp = mainArray.concat(directories);
tmp.forEach(directory => {
  const parent = tmp.find(item => item.Id === directory.ParentId);

  if(parent) {
      parent.SubDirectories = parent.SubDirectories || [];
      parent.SubDirectories.push(directory)
  }
});

console.log(mainArray)

我自己尝试的实现存在问题:会在重建JSON前移除顶层条目,代码如下:

tmp.forEach((directory) => {
  const parent = tmp.find((item) => item.Id === directory.ParentFk);

  if (parent) {
    parent.SubDirectories = parent.SubDirectories || [];

    const found = parent.SubDirectories.some((el) => el.Id === directory.Id);
    if (!found) {
      parent.SubDirectories.push(directory);
    } else {
      parent.SubDirectories = [];
    }
  }
}, []);

解决方案

现有实现的问题是重复判断逻辑错误,命中重复ID就清空整个父级子目录数组,自然会丢失正常数据。
最优的清空位置是在合并得到tmp数组之后、遍历构建目录树之前,统一初始化所有节点的SubDirectories为空数组,既可以一次性清空所有旧数据,也不用在后续循环里重复判断数组是否存在。

修正后的完整代码:

const mainArray = [{Id:1,Name:"test",SubDirectoryCount:10,Files:[]}];
const directories = [{Id:56,Name:"Client 2",SubDirectoryCount:1,ParentId:1,Files:[]},{Id:53,Name:"Client 3",SubDirectoryCount:1,ParentId:1,Files:[]},{Id:50,Name:"Client 4",SubDirectoryCount:1,ParentId:1,Files:[]},{Id:48,Name:"Client 5",SubDirectoryCount:1,ParentId:53,Files:[]},{Id:47,Name:"Client 5",SubDirectoryCount:1,ParentId:53,Files:[]},{Id:49,Name:"Client 5",SubDirectoryCount:1,ParentId:53,Files:[]}];

const tmp = mainArray.concat(directories);
// 统一清空所有节点的子目录数组,解决旧数据、重复初始化问题
tmp.forEach(item => item.SubDirectories = []);

tmp.forEach(directory => {
  const parent = tmp.find(item => item.Id === directory.ParentId);
  if(parent) {
    // 如果需要去重,在这里加存在性判断即可
    const exists = parent.SubDirectories.some(el => el.Id === directory.Id);
    if(!exists) {
      parent.SubDirectories.push(directory);
    }
  }
});

console.log(mainArray)

该方案的优势:

  • 逻辑拆分清晰,初始化和构建树的步骤分离,后续维护调试成本低
  • 仅需一次遍历完成所有数组初始化,不需要在每个循环中重复判断数组是否存在,性能更优
  • 完全避免了误清空父级全部子目录的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:36:04