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
相关产品推荐
相关产品推荐

