用reduce扁平化树形结构的核心是递归处理子节点并合并到数组:先推入当前节点,再对children递归调用并展开;支持自定义字段名、精简字段提取;超深树建议改用栈迭代避免栈溢出。

用 reduce 扁平化树形结构,核心是:每个节点递归处理子节点,再把当前节点和子节点结果合并到一个数组里。
基础思路:reduce + 递归 + 展开子节点
假设树节点格式为:{ id, name, children: [] }。我们对每一层节点调用 reduce,对当前节点自身推入结果,再对 children 递归调用并展开(用扩展运算符 [...] 或 concat)。
示例代码:
function flattenTree(arr) {
return arr.reduce((acc, node) => {
// 当前节点必须先加入
acc.push(node);
// 如果有子节点,递归扁平化后全部展开进 acc
if (Array.isArray(node.children) && node.children.length > 0) {
acc.push(...flattenTree(node.children));
}
return acc;
}, []);
}
支持自定义字段名(比如 children 不叫 children)
把子节点字段名作为参数传入,增强复用性:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
function flattenTree(arr, childrenKey = 'children') {
return arr.reduce((acc, node) => {
acc.push(node);
const children = node[childrenKey];
if (Array.isArray(children) && children.length > 0) {
acc.push(...flattenTree(children, childrenKey));
}
return acc;
}, []);
}
不修改原对象、只提取特定字段(如只取 id 和 name)
如果目标不是保留整个节点对象,而是生成精简的一维数组(例如 [{id: 1, name: 'A'}, {id: 2, name: 'B'}]),可以在 push 前做映射:
function flattenTreeSimple(arr, childrenKey = 'children') {
return arr.reduce((acc, node) => {
// 只保留需要的字段
acc.push({ id: node.id, name: node.name });
const children = node[childrenKey];
if (Array.isArray(children) && children.length > 0) {
acc.push(...flattenTreeSimple(children, childrenKey));
}
return acc;
}, []);
}
避免栈溢出:超深树建议用栈模拟递归(非 reduce,但更健壮)
reduce + 递归在树非常深时可能触发最大调用栈错误。此时可改用显式栈(while 循环),虽然不用 reduce,但更安全:
function flattenTreeIterative(arr, childrenKey = 'children') {
const stack = [...arr];
const result = [];
while (stack.length > 0) {
const node = stack.pop();
result.push(node);
const children = node[childrenKey];
if (Array.isArray(children)) {
stack.push(...children);
}
}
return result;
}
注意:这个版本是深度优先(类似递归顺序),若要广度优先,把 push(...children) 换成 unshift(...children) 即可。

















