递归遍历树形数组的核心是识别子节点字段(如children),对每个节点执行操作后再递归处理其子节点;需防护空数组或undefined,确保稳定处理任意深度树。

用递归遍历树形结构数组,核心是:识别子节点字段(如 children),对每个节点执行操作,再对其子节点递归调用自身。
识别树形结构特征
典型树形数组中,每个对象可能包含:
- 基础字段(如 id、name)
- 子节点数组字段(常见为 children,也可能是 subItems、nested 等)
- 子节点数组可能为空([])或不存在(undefined)
基础递归遍历(深度优先)
适用于打印、收集、校验等只读场景:
function traverseTree(nodes) {
if (!Array.isArray(nodes)) return;
<p>nodes.forEach(node => {
console.log(node.name); // 处理当前节点</p><pre class="brush:php;toolbar:false;">// 若存在 children 且为数组,则递归处理
if (Array.isArray(node.children)) {
traverseTree(node.children);
}}); }
// 调用 traverseTree(treeData);
递归并构建新结构(如扁平化)
返回一维数组,包含所有节点(含层级信息可选):
function flattenTree(nodes, level = 0) {
const result = [];
<p>nodes.forEach(node => {
result.push({
...node,
level // 可选:记录当前层级
});</p><pre class="brush:php;toolbar:false;">if (Array.isArray(node.children)) {
result.push(...flattenTree(node.children, level + 1));
}});
return result; }
// 使用 const flatList = flattenTree(treeData);
递归修改原数据(如添加 computed 字段)
直接在原节点上增加属性,注意避免循环引用或重复处理:
function enhanceTree(nodes) {
nodes.forEach(node => {
// 示例:添加 isLeaf 标志
node.isLeaf = !Array.isArray(node.children) || node.children.length === 0;
<pre class="brush:php;toolbar:false;">// 示例:计算全路径(假设 parent.id 已存在,或从上层传入 path)
if (Array.isArray(node.children)) {
enhanceTree(node.children);
}}); }
enhanceTree(treeData);
带中断能力的递归(如查找节点)
找到即返回,避免多余遍历:
function findNodeById(nodes, targetId) {
for (const node of nodes) {
if (node.id === targetId) {
return node;
}
if (Array.isArray(node.children)) {
const found = findNodeById(node.children, targetId);
if (found) return found;
}
}
return null;
}
<p>const target = findNodeById(treeData, 'abc123');
</p>递归本质是“处理自己 + 委托孩子”,关键在判断子节点是否存在且为数组;避免忘记空数组或 undefined 的防护,就能稳定处理任意深度的树。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











