新闻中心

J*aScript reduce 方法实现多层级对象数组的聚合与转换

2025-11-11
浏览次数:
返回列表

JavaScript reduce 方法实现多层级对象数组的聚合与转换

本文详细介绍了如何利用 j*ascript 的 `reduce` 方法将一个扁平的对象数组转换为具有多层级分组和数据聚合的复杂结构。通过逐层查找和创建新对象,我们能够高效地根据 `medico`、`rateio` 和 `convenio` 字段对数据进行归类并汇总 `subtotal`,从而实现灵活的数据重构。

引言

在现代Web开发中,数据处理是日常任务之一。我们经常需要将从后端获取的扁平化数据转换为更具结构化、便于前端展示或进一步处理的复杂形式。J*aScript 提供了多种数组方法来完成这类转换,其中 reduce 方法以其强大的聚合能力,在处理多层级分组和数据汇总场景时表现尤为出色。本教程将深入探讨如何利用 reduce 方法,将一个包含多个对象的数组,根据特定字段进行多层级嵌套分组,并对数值型字段进行累加。

场景描述:数据转换需求

假设我们有一个原始的销售明细数组 arr,其中每个对象包含 medico(医生)、rateio(费率)、convenio(协议)和 subtotal(小计)等信息:

const arr = [
  { medico: "med1", rateio: "rat1", convenio: "conv1", subtotal: 10 },
  { medico: "med2", rateio: "rat2", convenio: "conv2", subtotal: 10 },
  { medico: "med2", rateio: "rat2", convenio: "conv2", subtotal: 20 },
  { medico: "med1", rateio: "rat1", convenio: "conv3", subtotal: 20 },
  { medico: "med1", rateio: "rat1", convenio: "conv3", subtotal: 25 },
  { medico: "med2", rateio: "rat3", convenio: "conv4", subtotal: 15 },
  { medico: 'med2', rateio: 'rat4', convenio: 'conv3', subtotal: 10 },
];

我们的目标是将这个数组转换为一个按 medico、rateio 和 convenio 逐级分组的嵌套结构,并且在最内层对 subtotal 进行求和,最终结构如下所示:

const result = [
  {medico: "med1", grantotals:[
    {
      rateio: "rat1",
      grandtotals: [
        { convenio: "conv1", sum_subtotal: 10 },
        { convenio: "conv3", sum_subtotal: 45 }
      ]
    }
  ]},
  {medico: "med2", grantotals:[
      {
        rateio: "rat2",
        grandtotals: [
          { convenio: "conv2", sum_subtotal: 30 },
        ]
      },
      {
        rateio: "rat3",
        grandtotals: [
          { convenio: "conv4", sum_subtotal: 15 },
        ]
      },
      {
        rateio: "rat4",
        grandtotals: [
          { convenio: "conv3", sum_subtotal: 10 },
        ]
      }
    ]}
];

使用 reduce 方法实现转换

reduce() 方法对数组中的每个元素执行一个由您提供的 reducer 函数,将其结果汇总为单个返回值。它接收两个参数:一个 reducer 函数和一个可选的 initialValue。reducer 函数又接收四个参数:accumulator(累加器)、currentValue(当前值)、currentIndex(当前索引)和 array(源数组)。在这个场景中,我们将 accumulator 初始化为一个空数组 [],它将逐步构建最终的嵌套结构。

Tanka Tanka

具备AI长期记忆的下一代团队协作沟通工具

Tanka 146 查看详情 Tanka

核心逻辑

转换的核心思想是:遍历原始数组的每个对象,对于每个对象,我们都需要检查目标结构中是否已存在对应的 medico、rateio 和 convenio 层级。如果存在,则更新其 subtotal;如果不存在,则创建相应的层级和对象。

const result = arr.reduce((acc, obj) => {
  // 1. 查找或创建 medico 层级
  let existingMedico = acc.find((item) => item.medico === obj.medico);

  if (!existingMedico) {
    existingMedico = { medico: obj.medico, grantotals: [] };
    acc.push(existingMedico);
  }

  // 2. 查找或创建 rateio 层级
  let existingRateio = existingMedico.grantotals.find(
    (item) => item.rateio === obj.rateio
  );

  if (!existingRateio) {
    existingRateio = { rateio: obj.rateio, grandtotals: [] };
    existingMedico.grantotals.push(existingRateio);
  }

  // 3. 查找或创建 convenio 层级并累加 subtotal
  let existingConvenio = existingRateio.grandtotals.find(
    (item) => item.convenio === obj.convenio
  );

  if (existingConvenio) {
    existingConvenio.sum_subtotal += obj.subtotal;
  } else {
    existingRateio.grandtotals.push({
      convenio: obj.convenio,
      sum_subtotal: obj.subtotal,
    });
  }

  return acc;
}, []); // 初始累加器为一个空数组

console.log(result);

代码解析

上述代码通过 reduce 方法逐步构建了目标结构。具体步骤如下:

  1. 初始化累加器 (acc): reduce 方法的第二个参数 [] 将 acc 初始化为一个空数组,它将存储最终的医生(medico)列表。
  2. 遍历每个原始对象 (obj): 对于 arr 中的每一个元素 obj:
    • 处理 medico 层级:
      • 使用 acc.find() 检查当前 obj.medico 是否已存在于 acc 中。
      • 如果不存在 (!existingMedico),则创建一个新的 medico 对象,包含 medico 字段和空的 grantotals 数组,并将其添加到 acc 中。
      • 无论是否存在,existingMedico 都会指向当前 medico 对应的对象。
    • 处理 rateio 层级:
      • 在 existingMedico.grantotals 数组中,使用 find() 检查当前 obj.rateio 是否已存在。
      • 如果不存在 (!existingRateio),则创建一个新的 rateio 对象,包含 rateio 字段和空的 grandtotals 数组,并将其添加到 existingMedico.grantotals 中。
      • existingRateio 指向当前 rateio 对应的对象。
    • 处理 convenio 层级并累加 subtotal:
      • 在 existingRateio.grandtotals 数组中,使用 find() 检查当前 obj.convenio 是否已存在。
      • 如果存在 (existingConvenio),则直接将 obj.subtotal 加到 existingConvenio.sum_subtotal 上。
      • 如果不存在,则创建一个新的 convenio 对象,包含 convenio 字段和 obj.subtotal 作为 sum_subtotal,并将其添加到 existingRateio.grandtotals 中。
  3. 返回累加器: 每次迭代结束后,reduce 方法会返回更新后的 acc,作为下一次迭代的累加器。

注意事项与优化

  • 性能考量: 在上述实现中,我们使用了 Array.prototype.find() 方法进行查找。find() 方法的时间复杂度为 O(N),这意味着在每一层级查找现有元素时,最坏情况下都需要遍历该层级的整个数组。如果原始数组 arr 非常大,并且 medico、rateio、`conven

以上就是J*aScript reduce 方法实现多层级对象数组的聚合与转换的详细内容,更多请关注其它相关文章!


# 组中  # 房山区质量网站定制推广  # 连云港seo哪家便宜  # 九里网站建设报价  # 浙江新网站建设咨询热线  # 河南营销推广加盟平台  # 贵阳多语种网站建设  # 沂南营销推广多少钱  # 网站营销推广实训总结  # 哪些网站可以做推广吧  # seo竞价专员招聘  # 小计  # javascript  # 重构  # 创建一个  # 转换为  # 如何实现  # 遍历  # 不存在  # 累加器  # red  # 后端  # 前端  # java 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 怎样更改Windows系统的默认安装路径_避免C盘爆满的终极设置【技巧】  MAC如何将整个网页截长图_MAC使用Safari的导出为PDF或第三方工具  Win11怎么合并任务栏图标 Win11开启任务栏合并减少图标占空间【方法】  Typer应用中动态命令行参数的解析与处理  整合Supabase认证与Django模型:跨模式迁移的解决方案  高德地图怎么看全景照片_高德地图全景照片浏览教程  J*aScript数组对象转换:按指定键分组与值收集  QQ邮箱在线登录平台 QQ邮箱个人邮箱网页版入口  深入理解Google Cloud Datastore查询:祖先路径与数据一致性  2026年发布! 美少女养成动作RPG《神剑少女战记》发布实机演示  PyTorch模型训练准确率不提升:诊断与修复常见指标计算错误  谷歌浏览器最新官方入口链接 谷歌浏览器网页版官网导航  Golang如何使用const iota_Go iota常量计数器讲解  LINUX下如何进行磁盘分区_fdisk与parted工具在LINUX中的使用对比  KFC早餐时段怎么领特惠代码_KFC早餐订餐优惠代码获取与使用说明  c++中的std::basic_string的SSO优化_c++短字符串优化深度解析  MAC怎么让Dock栏只显示当前运行的应用_MAC终端命令实现极简Dock栏  mysql密码锁定怎么解锁_mysql密码锁定解锁后修改密码步骤  如何在 Excel Online 和 Google 表格中更改日期格式  如何仅使用CSS更改登录界面背景图像图标的颜色  小米汽车11月交付量突破40000台!雷军:将继续努力  微信网页版扫码登录入口 微信网页版二维码登录入口  4399网页游戏电脑版全新入口 4399电脑端在线玩指南  没有大陆身份证/银行卡如何实名微信? 亲测有效的几种方法分享  如何提高微信支付的安全性_微信支付安全防护与设置建议  知乎APP怎么管理已购盐选内容_知乎APP盐选内容购买记录与查看方法  126邮箱账号注册 电脑版登录入口  LocoySpider如何部署到云服务器_LocoySpider云部署的远程配置  TikTok搜索结果不显示如何解决 TikTok搜索刷新优化方法  CSS布局:解决全屏元素100%尺寸与外边距导致的页面溢出问题  动漫岛观看全网网 动漫岛在线正版动漫入口  React Hooks最佳实践:动态组件状态管理的组件化方案  C++ string find函数返回值npos详解_C++字符串查找失败的判断条件  蛙漫漫画免费阅读入口_蛙漫官方正版无广告纯净版  黑猫投诉统一入口官网 消费者权益保护投诉平台  如何创建独立于主系统的J*a运行环境_隔离式环境搭建策略  探索高级语言到原生C/C++的转译:挑战与内存管理策略  新三国志曹操传110级星符试炼夏侯渊极难攻略  BetterDiscord插件中安全更新用户简介的实践指南  快手官方唯一登录入口 谨防山寨钓鱼网站  Yandex官网搜索引擎免登录_俄罗斯Yandex一键直达入口  mcjs网页版在线存档 mcjs云存档登录入口  快手赚钱渠道_快手收益来源  拷贝漫画电脑版官网入口 拷贝漫画(PC版)在线直达  Golang如何处理RPC请求负载均衡_Golang RPC请求负载均衡策略与实践  sublime怎么进行远程开发编辑_配置rsub/rmate实现sublime编辑服务器文件  Go RPC HTTP服务正确实现与常见陷阱解析  在FastAPI中利用lifespan与依赖注入高效管理Redis连接池  漫蛙官网正版漫画入口 漫蛙2官方网页登录地址  UC浏览器官网入口2025最新 UC浏览器网页版正式地址 

搜索