如何实现将扁平API数组转为递归文件夹树形结构的函数?
解决方案:将扁平数组转换为无限层级树形结构
高效映射表实现(推荐)
这种方式通过构建节点映射表实现O(n)时间复杂度,适合处理大数据量:
function buildTree(data) { // 构建id到节点的映射,提前为每个节点初始化children数组 const nodeMap = new Map(); data.forEach(node => { nodeMap.set(node.id, { ...node, children: [] }); }); const treeRoots = []; data.forEach(node => { const currentNode = nodeMap.get(node.id); if (node.parent) { // 找到父节点并挂载当前节点 const parentNode = nodeMap.get(node.parent); parentNode?.children.push(currentNode); } else { // 无parent的节点作为根节点加入结果集 treeRoots.push(currentNode); } }); return treeRoots; }
递归实现(直观简洁)
如果偏好递归逻辑处理层级,可使用以下方式,代码更直观但性能略逊于映射表方案:
function buildTreeRecursive(data, parentId = null) { return data .filter(item => item.parent === parentId) .map(item => ({ ...item, // 仅FOLDER类型节点递归生成子节点,STANDARD类型无子项 children: item.type === 'FOLDER' ? buildTreeRecursive(data, item.id) : [] })); }
使用示例
// 你的原始API数据 const data = [ { id: 'node_292f637b-b33d-4d3d-bc96-8afc7ee1b949', conditions: 'string', type: 'FOLDER', }, { id: 'node_292f637b-b33d-4d3d-bc96-8afc7ee1b948', conditions: 'string', type: 'FOLDER', parent: 'node_292f637b-b33d-4d3d-bc96-8afc7ee1b949' }, { id: 'node_292f637b-b33d-4d3d-bc96-8afc7ee1b957', conditions: 'string', type: 'STANDARD', parent: 'node_292f637b-b33d-4d3d-bc96-8afc7ee1b948' }, { id: 'node_292f637b-b33d-4d3d-bc96-8afc7ee1b936', conditions: 'string', type: 'STANDARD' } ]; // 调用函数生成树形结构 const newData = buildTree(data); // 或 buildTreeRecursive(data) console.log(newData);
方案说明
- 映射表方案:通过一次遍历构建节点索引,再一次遍历完成子节点挂载,避免了重复遍历数组,性能最优。
- 递归方案:针对每个父节点递归筛选子节点,代码逻辑简单易懂,但每次筛选都要遍历整个数组,数据量较大时会影响性能。
- 你的原有代码仅处理了一级子节点,未对每个子节点递归查找深层子项,因此无法生成多级结构;上述两种方案均能自动处理无限层级的嵌套关系。
内容的提问来源于stack exchange,提问作者Julio Graffin
相关产品推荐
相关产品推荐

