数组方法转换数据层级结构需按场景选型:reduce用于父子聚合建树,reverse+map构建单链嵌套,flat/flatmap实现降维展平,递归+生成器处理未知深度,reduce+??=动态创建多级键路径。

用数组方法转换数据层级结构,关键在于匹配数据关系、选对遍历方式、避免副作用。不是所有数组方法都适合嵌套构建——reduce 和 map 最常用,但用途完全不同:reduce 用于按父子引用聚合生成树,map 用于顺序串联生成单链,而 flat / flatMap 更适合反向“展平”。
用 reduce 构建父子嵌套树(基于 id/parentId)
这是处理后端返回的扁平菜单、组织架构、目录列表的标准做法。核心是把每个节点按 parentId 归类,并递归挂载子节点。
- 先筛选出当前层级的根节点(如 parentId === '0' 或 null)
- 对每个匹配节点,调用自身函数递归查找它的子项(即 parentId === 当前节点 id)
- 用 reduce 遍历全量数组,只 push 符合条件的新节点,不修改原始数据
- 注意 children 字段名统一,别写成 childeren;浅拷贝节点对象防止污染源数据
用 reverse + map 构建单链式嵌套(顺序明确)
当数组本身已按层级顺序排列(比如路径节点、配置步骤),且目标是 key1 → key2 → key3 这样的单路径嵌套时,不能正向循环推入,必须逆序建立父子引用。
- 先调用 .reverse() 把数组倒过来,让末尾元素在前
- 用 reduce 累积器逐个把后一项设为前一项的 children 唯一值
- 这样能保证 key3 是 key2 的 children,key2 是 key1 的 children,层级不塌陷
- 原始数组中每个对象需预置空 children 数组,否则赋值会失败
用 flat 或 flatMap 处理多层嵌套数组
如果目标是降维——把 [[a], [b, [c]], d] 变成 [a, b, c, d],那就不用递归构造,而是展开。
- flat(Infinity) 可一次性展平任意深度,但兼容性要注意(IE 不支持)
- flatMap 结合 map 使用更灵活,比如 map 后返回数组,再自动拍平一层
- 对未知深度结构,仍推荐递归函数 + yield*(生成器)或简单递归判断类型
- 避免用 JSON.stringify + 正则提取,易出错且无法保留原始类型(如布尔、null)
用 reduce + 空值合并(??=)构建多级对象键路径
当数据靠 parent 字段(字符串)而非数字 id 关联时,比如表单配置 {key: "FIRST NAME", parent: "OWNER DATA"},需动态创建嵌套属性。
- 先用 reduce 遍历所有项,每项根据 parent 找到父对象位置
- 用 obj[parent] ??= {} 确保父级存在,再把当前项挂到其 children 下
- 顶级节点 parent 为空字符串或 null,单独收集为根节点
- 整个过程只需一次遍历,时间复杂度 O(n),比双重循环高效











