JavaScript/ReactJS中实现数组对象分组求和的SQL式聚合操作

JavaScript/ReactJS中实现数组对象分组求和的SQL式聚合操作

本文详细介绍了如何在JavaScript和ReactJS环境中,对数组对象进行类似SQL SUM和GROUP BY的聚合操作。通过迭代和中间对象存储的方式,演示了如何高效地根据指定属性(如ProjectType)对数组中的数值属性(如Amount和Hours)进行分组求和,最终生成结构化的聚合结果,避免了重复过滤和求和的繁琐步骤。

在现代前端应用开发中,尤其是在reactjs等框架中处理数据时,我们经常会遇到需要对数组中的对象进行分组和聚合计算的需求。这类似于关系型数据库中sql的sum和group by操作,即根据一个或多个键对数据进行分组,然后对每个组内的特定数值字段进行求和。

考虑以下一个包含项目信息的数组:

const frames = [  {    ProjectName: "Blue",    EmployeeGroup: false,    Amount: 50,    Hours: 15,    ProjectType: "Romeo",  },  {    ProjectName: "Red",    EmployeeGroup: false,    Amount: 20,    Hours: 5,    ProjectType: "Lima",  },  {    ProjectName: "Green",    EmployeeGroup: true,    Amount: 40,    Hours: 10,    ProjectType: "Lima",  }];

我们的目标是根据ProjectType对Amount和Hours进行求和,最终得到如下结构的数据:

[  {    ProjectType: "Lima",    TotalAmount: 60,    TotalHours: 15,  },  {    ProjectType: "Romeo",    TotalAmount: 50,    TotalHours: 15,  }]

直接使用array.filter和array.reduce组合虽然可以实现对单一ProjectType的求和,但如果需要对所有ProjectType进行聚合,这种方法会导致多次遍历和重复逻辑,效率较低且代码冗余。

实现分组求和的策略

为了高效地实现类似SQL GROUP BY和SUM的功能,我们可以采用一种常见的JavaScript模式:利用一个中间对象作为累加器,在一次遍历中完成分组和求和。

立即学习“Java免费学习笔记(深入)”;

核心实现步骤

初始化一个空对象作为累加器:这个对象将用于存储按ProjectType分组后的聚合数据。ProjectType将作为这个对象的键。遍历原始数组:对frames数组中的每个元素进行迭代。检查并初始化分组项:在每次迭代中,检查当前元素的ProjectType是否已作为键存在于累加器对象中。如果不存在,则为该ProjectType创建一个新的聚合对象,并初始化TotalAmount和TotalHours为0。如果已存在,则直接使用现有聚合对象。累加数值:将当前元素的Amount和Hours累加到对应ProjectType的聚合对象中的TotalAmount和TotalHours。提取最终结果:遍历完成后,累加器对象包含了所有分组的聚合数据。使用Object.values()方法将这个对象的值(即每个ProjectType的聚合结果)转换为一个数组,从而得到最终的期望输出。

示例代码

const frames = [  { ProjectName: "Blue", EmployeeGroup: false, Amount: 50, Hours: 15, ProjectType: "Romeo" },  { ProjectName: "Red", EmployeeGroup: false, Amount: 20, Hours: 5, ProjectType: "Lima" },  { ProjectName: "Green", EmployeeGroup: true, Amount: 40, Hours: 10, ProjectType: "Lima" }];const items = {}; // 初始化一个空对象作为中间累加器// 使用 forEach 遍历原始数组frames.forEach( ({ ProjectType, Amount, Hours }) => {  // 检查当前 ProjectType 是否已存在于累加器中  if (!items[ProjectType]) {    // 如果不存在,则为该 ProjectType 初始化一个新的聚合对象    items[ProjectType] = { ProjectType, TotalAmount: 0, TotalHours: 0 };  }  // 累加 Amount 和 Hours  items[ProjectType].TotalAmount += Amount;  items[ProjectType].TotalHours += Hours;});// 使用 Object.values() 将累加器对象转换为最终的数组结果const output = Object.values(items);console.log(output);/*输出结果:[  { ProjectType: 'Lima', TotalAmount: 60, TotalHours: 15 },  { ProjectType: 'Romeo', TotalAmount: 50, TotalHours: 15 }]*/

代码解析

const items = {};: items是一个普通JavaScript对象,它将以ProjectType的值作为键,存储每个项目类型的聚合数据。frames.forEach( ({ ProjectType, Amount, Hours }) => { … });: 我们使用forEach方法遍历frames数组。这里使用了ES6的对象解构,直接从当前frame对象中提取了ProjectType、Amount和Hours这三个属性,使代码更简洁易读。if (!items[ProjectType]) { … }: 这是分组逻辑的关键。它检查items对象中是否已经存在以当前ProjectType为键的属性。如果不存在(即这是我们第一次遇到这个ProjectType),就创建一个新的对象,并将其ProjectType、TotalAmount和TotalHours初始化。items[ProjectType].TotalAmount += Amount;items[ProjectType].TotalHours += Hours;: 无论ProjectType是首次出现还是已经存在,我们都将当前Amount和Hours累加到对应ProjectType的TotalAmount和TotalHours上。const output = Object.values(items);: forEach循环结束后,items对象看起来会是这样:

{  "Lima": { ProjectType: "Lima", TotalAmount: 60, TotalHours: 15 },  "Romeo": { ProjectType: "Romeo", TotalAmount: 50, TotalHours: 15 }}

Object.values()方法用于返回一个给定对象自身的所有可枚举属性值的数组,顺序与for…in循环给出的顺序一致。这样,我们就得到了期望的数组格式结果。

注意事项与总结

效率:这种方法只需要对原始数组进行一次遍历(单趟操作),相比于多次filter和reduce的组合,在处理大型数据集时效率更高。可读性:代码逻辑清晰,易于理解,符合JavaScript开发者常用的模式。灵活性:如果需要聚合更多字段,只需在初始化时添加相应字段,并在累加步骤中增加对应的求和操作即可。ReactJS环境:在React组件中,你可以在useEffect钩子中执行此类数据处理,或者在组件状态更新时调用此函数,以确保数据始终是最新的。

通过这种迭代加中间对象的策略,我们可以有效地在JavaScript中模拟SQL的GROUP BY和SUM操作,实现复杂的数据聚合需求,为前端应用的数据展示和分析提供强大的支持。

以上就是JavaScript/ReactJS中实现数组对象分组求和的SQL式聚合操作的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1528240.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
实现可搜索下拉复选框的“全选”功能
上一篇 2025年12月20日 20:06:34
JavaScript:显示多维数组中一维数组的变量名
下一篇 2025年12月20日 20:06:46

相关推荐

  • 如何使用Dagger和Retrofit在运行时动态添加身份验证头?

    Dagger 和 Retrofit 运行时动态添加身份验证头部 本文探讨如何在 Dagger 和 Retrofit 中动态添加身份验证头部。 当需要基于更新后的令牌创建 Retrofit 实例时,有多种方法可供选择。 利用依赖注入范围 (Scope) 通过自定义 Scope,您可以控制 Retrof…

    2026年9月1日
    000
  • 首个基于统计学的线性注意力机制ToST,高分拿下ICLR Spotlight

    首个基于统计学的线性注意力机制ToST,高分拿下ICLR Spotlight首个基于统计学的线性注意力机制ToST,高分拿下ICLR Spotlight首个基于统计学的线性注意力机制ToST,高分拿下ICLR Spotlight首个基于统计学的线性注意力机制ToST,高分拿下ICLR Spotlight

    加州大学伯克利分校吴梓阳博士及其团队提出了一种新型transformer架构——token statistics transformer (tost),其核心是线性时间复杂度的注意力机制。这项研究成果已发表在iclr 2025,并被选为spotlight论文。马毅教授将在今年四月iclr大会上进行主…

    2026年9月1日 用户投稿
    200
  • ROS1/2机器人之从命令调用到程序编写

    难度级别: 容易☞命令调用 困难☞程序编写 命令调用简单案例 ROS1: rosrun package-name executable-name ROS2: ros2 run package-name executable-name 比如启动键盘遥控turtlesim ROS1: 大多数 ROS1 …

    2026年9月1日
    000
  • Swagger文档如何区分API新增和更新场景的参数要求?

    Swagger文档参数注释如何区分API新增和更新场景? 在设计RESTful API时,新增和更新操作对参数的要求往往不同。本文探讨如何在Swagger文档中清晰地表达这种差异。 考虑一个包含create和update方法的API控制器,以及User对象: void create(@Validat…

    2026年9月1日
    000
  • Spring异步线程池堆积:如何避免批量保存导致的性能瓶颈?

    优化Spring异步线程池,避免数据保存瓶颈 在使用Spring异步线程池处理批量数据保存到Redis时,您可能遇到线程池堆积的问题:当线程数达到上限后,任务积压在队列中,导致批量保存(例如,每20条记录一次)效率低下,每秒仅保存少量数据。 调整线程池参数(最大线程数、空闲线程数、队列长度和拒绝策略…

    2026年9月1日
    100
  • PHP cURL查询Notion数据库:掌握正确的过滤条件构建方法

    本教程详细阐述了使用PHP cURL向Notion API查询数据库时,如何正确构建包含过滤条件的POST请求体。核心问题在于,过滤条件必须嵌套在请求载荷的filter键下,而非直接作为顶级属性。文章通过对比错误与正确的代码示例,指导开发者精确地筛选Notion数据库数据,避免获取冗余信息,从而提高…

    2026年9月1日
    100
  • Java大数据中如何快速精准匹配句子中的关键词?

    Java大数据环境下的快速精准关键词匹配 本文探讨如何在Java大数据环境下,高效地从包含20万到50万条记录的词库中,快速精准地匹配句子中的关键词。词库存储介质可以是列表、字典、Redis或数据库。 高效算法:基于前缀树的匹配 为了实现高效匹配,我们采用基于前缀树(Trie树)的算法。该算法将每个…

    2026年9月1日
    100
  • Java Collections.frequency方法如何统计频率

    Collections.frequency方法用于统计集合中某元素出现次数,接收集合和目标元素为参数,遍历集合通过equals()比较并返回匹配次数;适用于List等Collection类型,支持自定义对象(需重写equals),可统计null,但集合为null时抛异常,时间复杂度O(n),对Set…

    2026年9月1日
    300
  • java学习应用篇|windows安装JDK及配置环境变量

    java学习应用篇|windows安装JDK及配置环境变量java学习应用篇|windows安装JDK及配置环境变量java学习应用篇|windows安装JDK及配置环境变量java学习应用篇|windows安装JDK及配置环境变量

    学习前言 实际上,本系统中最有价值的内容已经在前两篇文章中介绍完毕,接下来的内容主要是对前面知识的应用。新知识层出不穷,每隔几天就会有新的概念和框架出现。我们在本系列学习中,力求通过基本的学习方法来深入探究代码的本质,这样无论将来出现什么新的知识点,我们都能迅速学习并应用。小刀的水平有限,欢迎大家在…

    2026年9月1日 用户投稿
    200
  • 如何利用MySQL唯一索引和分布式锁/数据库锁防止特定时间段内的数据重复插入?

    如何利用MySQL唯一索引和锁机制避免特定时间段内的数据重复插入? 本文探讨如何防止在特定时间范围内(例如10:15-11:15)向MySQL数据库插入重复数据。直接使用MySQL唯一索引无法完全解决此问题,因为时间戳是动态变化的。 解决方案: 1. 高效方案:利用分布式锁(例如Redis) 对于高…

    2026年9月1日
    200
  • ChatGPT怎么用_ChatGPT注册登录与基础使用教程

    答案是注册并掌握提问技巧后,ChatGPT能成为高效工具。需通过官网注册,验证邮箱和手机号,登录后可在聊天界面输入问题,利用上下文记忆、角色设定、明确指令等技巧提升回答质量,免费版适合初试,Plus版则提供GPT-4、插件、数据分析等高级功能,适合高频深度使用者。 ☞☞☞AI 智能聊天, 问答助手,…

    2026年9月1日
    200
  • Dagger2+Retrofit:如何在用户登录后动态添加身份验证请求头?

    Dagger2与Retrofit:运行时添加身份验证头 用户登录成功并获取令牌后,如何利用Dagger2在Retrofit请求中动态添加身份验证头?本文探讨几种可行方案。 方案一:重新构建组件 获取令牌后,销毁提供Retrofit实例的组件,重新构建一个新组件,并请求新的Retrofit实例。此新实…

    2026年9月1日
    100
  • MySQL唯一索引如何实现基于时间段的约束?

    MySQL如何实现基于时间段的唯一索引约束? 如何在MySQL中创建唯一索引,以确保同一时间段内只允许插入一条记录?直接用索引无法实现,但我们可以通过以下两种方法解决: 方法一:利用分布式锁(高频数据场景推荐) 此方法适合数据插入频率较高的场景。 流程如下: 使用Redis等分布式锁服务。插入数据前…

    2026年9月1日
    200
  • 怎么在VSCode安装Pylint_VSCode配置Python代码检查工具Pylint教程

    答案是安装并配置Pylint扩展与Python包,再在VSCode中启用并自定义规则。首先安装VSCode的Pylint扩展,然后通过pip install pylint在Python环境中安装库;接着在settings.json中设置”python.linting.pylintEnab…

    2026年9月1日
    700
  • PHP集成Notion API:数据库查询过滤实战指南

    本文旨在解决PHP通过cURL调用Notion API进行数据库查询时,因请求体结构不当导致过滤无效的问题。核心内容是阐明Notion API的POST /v1/databases/{database_id}/query接口要求将所有过滤条件封装在filter键下,并提供正确的PHP代码示例,确保开…

    2026年9月1日
    100
  • 怎么清除VSCode的设置_VSCode恢复默认设置与用户配置清除教程

    清除VSCode设置需删除用户配置文件夹,路径因系统而异,可选择完全或部分清除,建议先备份;用户设置影响全局,工作区设置仅限当前项目,优先级依次升高;扩展设置通常存于settings.json,卸载或手动删除可清除,部分数据可能残留;也可通过命令面板清空设置或重置单项,同步功能需注意云端覆盖。 清除…

    2026年9月1日
    300
  • win11安装报错0xc1900101的解决方法

    win11安装报错0xc1900101的解决方法win11安装报错0xc1900101的解决方法win11安装报错0xc1900101的解决方法win11安装报错0xc1900101的解决方法

    在将个人电脑升级至windows 11操作系统时,不少用户可能会遭遇安装失败的情况,具体表现为出现错误代码0xc1900101,这会阻碍新系统的顺利安装。接下来,让我们一起看看如何解决windows 11安装过程中出现的0xc1900101错误问题。 方法一:清除更新并重新安装 1、首先,点击Win…

    2026年9月1日 用户投稿
    300
  • Piti插件怎样添加过渡动画效果_Piti插件添加过渡动画效果步骤

    首先启用Piti插件动画模块,再设置元素初始与目标状态,接着配置过渡时间及缓动函数,然后绑定悬停或点击等触发事件,最后导出CSS或JSON代码用于开发或在Figma中预览动画效果。 如果您在使用Piti插件进行页面元素设计时,希望增强视觉流畅性,可以通过添加过渡动画效果来实现元素状态变化的平滑呈现。…

    2026年9月1日
    1400
  • Python环境安装教程

    Python环境安装教程Python环境安装教程Python环境安装教程Python环境安装教程

    引言 通常我们将#%#$#%@%@%$#%$#%#%#$%@_23eeeb4347bdd26bfc++6b7ee9a3b755dd和java语言归为解释型语言,而对于c/c++则归为编译型语言。 安装Python解释器最新版本下载 官网下载(https://www.Python.org/) 选择最新…

    2026年9月1日 用户投稿
    400
  • MySQL的Explain执行计划怎么看_关键指标如何理解?

    MySQL的Explain执行计划怎么看_关键指标如何理解?MySQL的Explain执行计划怎么看_关键指标如何理解?MySQL的Explain执行计划怎么看_关键指标如何理解?MySQL的Explain执行计划怎么看_关键指标如何理解?

    mysql的explain执行计划用于分析sql语句的执行方式,帮助优化查询性能。1. id字段表示执行顺序,值越大优先级越高;2. select_type表示查询类型,如simple、primary、subquery等;3. type显示查找方式,最佳为const、eq_ref,最差为all;4.…

    2026年9月1日 用户投稿
    200

发表回复

登录后才能评论
关注微信