如何优化JS树形生成函数,支持指定根父ID与生成深度?
优化树形结构生成函数:支持指定根节点与深度
原始数据集
const dataset=[ { id:1, a:5, parentId:null}, { id:2, a:6, parentId:1}, { id:3, a:7, parentId:2}, { id:4, a:8, parentId:1}, { id:5, a:8, parentId:3}, ]
原有树形结构生成函数
原createDataTree函数可将上述数据集转换为完整树形结构,代码如下:
const result = createDataTree(dataset, 'parentIdField') const createDataTree = (dataset, parentIdField = 'parentId') => { const hashTable = Object.create(null); dataset.forEach((aData) => { return hashTable[aData.id] = { ...aData, children: [] }; }); const dataTree = []; dataset.forEach((aData) => { if (aData[parentIdField]) hashTable[aData[parentIdField]].children.push(hashTable[aData.id]); else dataTree.push(hashTable[aData.id]); }); return dataTree; };
需求说明
需要优化该函数,新增rootParentId和depth两个参数,使其能够生成从指定根父ID开始、指定深度的树形结构。例如传入rootParentId=2、depth=1时,预期输出结果为:
[ {id:2, a:6, parentId:1, children:[ { id:3, a:7, parentId:2, children: null} ] } ]
最优实现方案
实现思路
- 保留哈希表预处理逻辑,实现O(1)时间复杂度的节点查找,保证整体性能为O(n)
- 支持从任意节点作为根节点构建树:若
rootParentId为null,则沿用原有逻辑选择parentId为null的节点;否则直接选取id等于rootParentId的节点作为根节点 - 通过递归控制树的深度:以根节点为第0层,当节点层级达到指定
depth时,将其children设为null并停止递归,确保只生成指定深度的结构
优化后的函数代码
const createDataTree = (dataset, parentIdField = 'parentId', rootParentId = null, depth = Infinity) => { // 构建哈希表,快速映射节点ID到节点对象 const hashTable = Object.create(null); dataset.forEach(aData => { hashTable[aData.id] = { ...aData, children: [] }; }); // 确定根节点集合 const rootNodes = rootParentId === null ? dataset.filter(item => item[parentIdField] === null).map(item => hashTable[item.id]) : [hashTable[rootParentId]].filter(Boolean); // 过滤不存在的根节点情况 // 递归构建指定深度的子树 const buildSubTree = (node, currentLevel) => { // 当前节点层级已达到指定深度,终止递归并设置children为null if (currentLevel >= depth) { node.children = null; return; } // 遍历子节点,递归处理下一层级 node.children.forEach(child => buildSubTree(child, currentLevel + 1)); }; // 处理所有根节点 rootNodes.forEach(node => buildSubTree(node, 0)); return rootNodes; };
测试验证
调用createDataTree(dataset, 'parentId', 2, 1)时,输出结果与预期一致:
[ { "id": 2, "a": 6, "parentId": 1, "children": [ { "id": 3, "a": 7, "parentId": 2, "children": null } ] } ]
关键优势
- 兼容性强:保留原有参数默认值,不影响旧代码使用
- 性能高效:哈希表预处理保证节点查找效率,整体时间复杂度仍为O(n)
- 逻辑清晰:递归层级计数精准控制树的深度,符合需求定义
- 鲁棒性高:自动过滤不存在的根节点,避免报错
内容的提问来源于stack exchange,提问作者Mehran Ishanian
相关产品推荐
相关产品推荐

