【前端】【功能函数】treeMapEach,对每个节点进行自定义转换的实用函数

一、功能说明

这是一个递归遍历树形结构数据,并对每个节点进行自定义转换的实用函数。它会对原始树中的每个节点执行 conversion 函数,最终生成一个包含转换后结果的新树结构。

二、核心作用

  1. 树形结构遍历:深度优先递归遍历所有子节点
  2. 数据格式转换:通过自定义函数修改节点数据结构
  3. 字段映射 :可指定子节点字段名称(默认 children
  4. 非破坏性操作:返回新对象,不修改原始数据

三、代码注释解析

typescript 复制代码
/**
 * 递归映射树形结构
 * @param data 当前节点数据
 * @param children 子节点字段名(默认'children')
 * @param conversion 节点转换函数
 */
export const treeMapEach = (
  data: any,
  { children = 'children', conversion }: { children?: string; conversion: Fn }
) => {
  // 判断是否存在有效子节点
  const haveChildren = Array.isArray(data[children]) && data[children].length > 0
  
  // 执行当前节点转换
  const conversionData = conversion(data) || {}
  
  // 递归处理子节点
  if (haveChildren) {
    return {
      ...conversionData, // 合并转换后的数据
      [children]: data[children].map((i: number) => // 映射子节点
        treeMapEach(i, { children, conversion })
      )
    }
  } 
  // 无子节点时直接返回
  else {
    return { ...conversionData }
  }
}

四、使用示例

typescript 复制代码
// 示例数据
const treeData = {
  id: 1,
  name: 'Root',
  children: [
    { id: 2, name: 'Child', children: [
      { id: 3, name: 'Grandchild' }
    ]}
  ]
}

// 转换函数:将 name 转为 label,并添加 level 字段
const convertedTree = treeMapEach(treeData, {
  conversion: (node) => ({
    label: node.name,
    level: node.id.toString()
  })
})

/* 输出结果:
{
  label: "Root",
  level: "1",
  children: [
    {
      label: "Child",
      level: "2",
      children: [
        { label: "Grandchild", level: "3" }
      ]
    }
  ]
}
*/

五、应用场景详解

  1. 数据格式化:API数据 → 前端所需格式
  2. 字段重命名:统一不同数据源的字段命名
  3. 数据过滤:通过转换函数排除特定节点
  4. 添加元数据:为每个节点附加计算属性
  5. 结构简化:去除冗余字段,精简数据结构

六、技术文章

《树形结构映射工具深度解析》

在处理树形数据时,我们常需要将原始数据转换为特定格式。treeMapEach 函数提供了一种优雅的解决方案,其核心优势在于:

1. 灵活配置

  • 支持自定义子节点字段名,兼容不同数据格式
  • 转换函数自由定义,满足各种业务需求
  • 保留原始数据结构,仅修改指定内容

2. 实现原理

采用深度优先遍历策略,通过递归调用实现层级处理。每次递归都会:

  • 执行当前节点转换
  • 判断子节点存在性
  • 递归处理子节点数组

3. 性能特点

  • 时间复杂度:O(n) 线性复杂度
  • 空间复杂度:O(n) 生成新对象
  • 尾递归优化:适合处理深层树结构

4. 扩展应用

typescript 复制代码
// 示例1:数据脱敏
treeMapEach(userData, {
  conversion: (node) => ({
    ...node,
    phone: node.phone.replace(/^(\d{3})\d+(\d{4})$/, '$1****$2')
  })
})

// 示例2:权限过滤
treeMapEach(menuData, {
  conversion: (node) => node.visible ? node : null
}).children.filter(Boolean)

5. 注意事项

  • 确保树结构无循环引用
  • 转换函数应返回对象类型
  • 大数据量时建议使用迭代方式
  • 建议配合TypeScript类型定义使用

该函数已成功应用于多个实际项目,包括:

  • 组织架构树展示
  • 商品分类系统
  • 权限管理系统
  • 可视化决策树

通过合理使用 treeMapEach,开发者可以显著提升树形数据处理的开发效率,同时保证代码的可维护性和扩展性。

相关推荐
coderHing[专注前端]3 分钟前
告别 try/catch 地狱:用三元组重新定义 JavaScript 错误处理
开发语言·前端·javascript·react.js·前端框架·ecmascript
UIUV20 分钟前
JavaScript中this指向机制与异步回调解决方案详解
前端·javascript·代码规范
momo10020 分钟前
IndexedDB 实战:封装一个通用工具类,搞定所有本地存储需求
前端·javascript
liuniansilence20 分钟前
🚀 高并发场景下的救星:BullMQ如何实现智能流量削峰填谷
前端·分布式·消息队列
再花20 分钟前
在Angular中实现基于nz-calendar的日历甘特图
前端·angular.js
GISer_Jing32 分钟前
今天看了京东零售JDS的保温直播,秋招,好像真的结束了,接下来就是论文+工作了!!!加油干论文,学&分享技术
前端·零售
Mapmost39 分钟前
【高斯泼溅】如何将“歪头”的3DGS模型精准“钉”在地图上,杜绝后续误差?
前端
废春啊1 小时前
前端工程化
运维·服务器·前端
爱上妖精的尾巴1 小时前
6-9 WPS JS宏Map、 set、get、delete、clear()映射的添加、修改、删除
前端·wps·js宏·jsa
爱分享的鱼鱼2 小时前
对比理解 Vue 响应式 API:data(), ref、reactive、computed 与 watch 详解
前端·vue.js