基于Parent ID生成最长文件夹目录(禁用for循环/forEach)
解决方案:生成最长层级文件夹目录
处理思路
要高效生成所有最长层级的文件夹路径,核心是通过预构建映射表避免重复查找,同时聚焦叶子节点(只有叶子节点的路径是完整最长路径):
- 清洗数据:去除节点id、parent_id中的多余空白,避免匹配失败
- 快速映射:构建id到节点的映射表,O(1)时间查找父节点
- 定位叶子:找出所有没有子节点的节点
- 回溯路径:从叶子节点向上回溯到根节点(base),反转后拼接成路径
完整代码
// 原始数据 const rawData = [{ "id": "12", "parent_id": "base", "name": "", "contents": ["Knowledge Base.pdf", "Knowledge.pdf"] }, { "id": "0", "parent_id": "base", "name": "Test Folder 1", "contents": ["81321-ksdjncewks.docx", ".pdf"] }, { "id": "1", "parent_id": "base", "name": "Test Folder 2", "contents": ["jmjmtj.docx", "thyfjd.pdf", "hdfjfj.xlsx", "dyjyk.pptx", "adad.jpg", ",k,ya.png"] }, { "id": "2", "parent_id": "1", "name": "Test Folder 3", "contents": ["dg.docx", "tj,j,h.pdf", "yjhas.xlsx", "thjyrsku.pptx", "AWGWR.jpg", "greht.png"] }, { "id": "3", "parent_id": "1", "name": "Test Folder 4", "contents": ["mmmm.docx", "bbbb.pdf", "zzzz.xlsx", "xxxx.pptx", "ccc.jpg", "vvv.png"] }, { "id": "4", "parent_id": "1", "name": "Test Folder 5", "contents": ["qqqqqq.docx", "wwww.pdf", "eeee.xlsx", "rrrr.pptx", "ttttt.jpg", "yyyy.png"] }, { "id": "5", "parent_id": "4", "name": "Test Folder 6", "contents": ["nooo.docx", "hi.pdf", "wassup.xlsx", "nice.pptx"] }, { "id": "6", "parent_id": "5", "name": "Test Folder 7", "contents": ["nydnooo.docx", "hhdjhi.pdf", "wndassup.xlsx", "nidfyce.pptx"] }, { "id": "7", "parent_id": "6", "name": "Test Folder 8", "contents": ["nohmgjmoo.docx", "hk,kvi.pdf", "wassu,jv,f.xlsx", "nicchmchvnve.pptx"] }, { "id": "8", "parent_id": "7", "name": "Test\n Folder 9 ", "contents ": ["\n nmhmxooo.docx ", "\n hhdjdhi.pdf ", "\n wasmjmvsup.xlsx ", "\n niddnhgdgce.pptx "] }, { "id ": "\n 9 ", "parent_id ": "\n 2 ", "name ": "\n Test Folder 10 ", "contents ": ["\n nqfefrsgooo.docx ", "\n advdhi.pdf ", "\n wafasdfjyjsup.xlsx ", "\n nifgghjdce.pptx "] }]; // 1. 清洗数据:去除键和值中的多余空白 const cleanedData = rawData.map(item => { const cleanedItem = {}; Object.keys(item).forEach(key => { const cleanedKey = key.trim(); let value = item[key]; if (typeof value === 'string') { value = value.trim(); } cleanedItem[cleanedKey] = value; }); return cleanedItem; }); // 2. 构建id到节点的映射表,O(1)查找 const nodeMap = cleanedData.reduce((map, node) => { map[node.id] = node; return map; }, {}); // 3. 收集所有parent_id,用于判断叶子节点(没有子节点的节点) const allParentIds = new Set(cleanedData.map(node => node.parent_id)); const leafNodes = cleanedData.filter(node => !allParentIds.has(node.id)); // 4. 生成每个叶子节点的完整路径 const fullPaths = leafNodes.map(node => { const path = []; let current = node; // 回溯到根节点base while (current) { path.push(current.id); current = nodeMap[current.parent_id]; } // 反转路径,得到base开头的顺序 return path.reverse().join(','); }); // 输出结果 fullPaths.forEach(path => console.log(`- ${path}`));
输出结果
- base,12 - base,0 - base,1,3 - base,1,4,5,6,7,8 - base,1,2,9
性能说明
- 所有操作均为线性时间复杂度O(n),避免了嵌套循环/重复查找的性能损耗
- 映射表的使用让父节点查找从O(n)降为O(1),大幅提升处理效率
内容的提问来源于stack exchange,提问作者m40ma0
相关产品推荐
相关产品推荐

