如何收集n层嵌套数组对象所有子ID并修复现有JS递归代码问题
问题分析
原代码错误点
- 递归调用参数逻辑错误:遍历到子节点后,仅传入了该子节点
child数组的第一个元素data?.child[0]执行递归,若子节点的child数组存在多个元素,除第一个外的所有子节点的后代都会被完全遗漏 - 全局变量污染:依赖外部全局变量
array1存储结果,多次调用函数会导致结果累积,不符合无副作用的函数设计规范 - 变量命名冲突:函数参数和forEach遍历的元素都命名为
data,可读性差,容易引发逻辑混淆 - (可选,视需求而定)根节点ID未收集:如果需求需要包含最顶层节点的ID,原代码没有将传入的根节点ID加入结果数组
修复后的递归实现
const data = { name: '1', id: '05f770d5', child: [ { name: '2', id: '0ecfc8e1', child: [ { name: '3', id: '2e1eb75c', child: [], }, ], }, { name: '1c', id: 'b9ee9864', child: [ { name: '8', id: '575f4760', child: [], }, ], }, ], }; // 版本1:包含根节点ID,无全局污染 function collectAllIds(node, result = []) { result.push(node.id); node.child.forEach(childNode => collectAllIds(childNode, result)); return result; } const allIds = collectAllIds(data); console.log(allIds); // 输出:['05f770d5', '0ecfc8e1', '2e1eb75c', 'b9ee9864', '575f4760'] // 版本2:仅收集所有子节点ID,和原代码初始需求对齐,不含根节点 function collectChildIds(node, result = []) { node.child.forEach(childNode => { result.push(childNode.id); collectChildIds(childNode, result); }); return result; } const childIds = collectChildIds(data); console.log(childIds); // 输出:['0ecfc8e1', '2e1eb75c', 'b9ee9864', '575f4760']
其他可行实现方案
迭代实现(深度优先遍历,避免递归栈溢出,适合嵌套层级极深的场景)
function collectAllIdsIterative(root) { const result = []; const stack = [root]; while (stack.length > 0) { const current = stack.pop(); result.push(current.id); // 子节点倒序入栈保证遍历顺序和递归一致,不需要顺序可直接正序push for (let i = current.child.length - 1; i >= 0; i--) { stack.push(current.child[i]); } } return result; }
广度优先遍历实现
function collectAllIdsBfs(root) { const result = []; const queue = [root]; while (queue.length > 0) { const current = queue.shift(); result.push(current.id); queue.push(...current.child); } return result; }
内容的提问来源于stack exchange,提问作者Rama Devi
相关产品推荐
相关产品推荐

