js 如何使用groupBy对对象数组进行分组

使用reduce是javascript中对对象数组分组最常用且灵活的方法;1. 通过reduce遍历数组,以目标属性值作为键,将对象归类到累加器(对象或map)中;2. 当累加器为普通对象时,适用于字符串键,若需支持任意类型键则应使用map;3. 社区已推动object.groupby和map.groupby进入stage 3提案,未来或将成为原生方法;4. 第三方库如lodash提供_.groupby等便捷函数,语法更简洁且经过优化,适合复杂项目使用;5. 具体选择取决于性能需求、键类型及是否允许引入外部依赖,目前reduce仍是兼容性和控制力最佳的方案。

js 如何使用groupBy对对象数组进行分组

在JavaScript中,如果你想对一个对象数组进行分组,目前原生语言并没有一个直接的

groupBy

方法(尽管新提案正在路上)。不过,这并不妨碍我们通过一些常见的编程模式来优雅地实现这个功能,最常用且灵活的方式就是结合

Array.prototype.reduce()

方法。

解决方案

要使用JavaScript对对象数组进行分组,最直接和广泛接受的方法是利用

reduce

迭代器。这个方法允许你遍历数组,并根据一个累加器(通常是一个空对象或Map)来构建最终的分组结果。

const people = [  { id: 1, name: 'Alice', city: 'New York' },  { id: 2, name: 'Bob', city: 'London' },  { id: 3, name: 'Charlie', city: 'New York' },  { id: 4, name: 'David', city: 'Paris' },  { id: 5, name: 'Eve', city: 'London' },];// 根据 'city' 属性进行分组const groupedByCity = people.reduce((acc, person) => {  const key = person.city;  if (!acc[key]) {    acc[key] = []; // 如果这个城市还没有对应的数组,就创建一个  }  acc[key].push(person); // 将当前人添加到对应城市的数组中  return acc;}, {}); // 初始累加器是一个空对象console.log(groupedByCity);/*输出大致结构:{  "New York": [    { id: 1, name: 'Alice', city: 'New York' },    { id: 3, name: 'Charlie', city: 'New York' }  ],  "London": [    { id: 2, name: 'Bob', city: 'London' },    { id: 5, name: 'Eve', city: 'London' }  ],  "Paris": [    { id: 4, name: 'David', city: 'Paris' }  ]}*/

这段代码的核心在于

reduce

的回调函数。它接收一个累加器

acc

和当前元素

person

。我们以

person.city

作为键(key),检查

acc

中是否已存在这个键。如果不存在,就为它创建一个空数组;然后,将当前的

person

对象推入到这个数组中。最终,

reduce

返回的就是一个以城市名为键,值为对应人物数组的对象。

为什么JavaScript原生没有

groupBy

方法?

这确实是个有意思的问题,尤其是在其他一些语言或库中,

groupBy

是个非常常见的操作。JavaScript作为一门历史悠久的语言,其核心库的设计哲学在早期可能更侧重于提供基础的、通用的构建块,而不是过于高层的、特定场景的功能。像

reduce

map

filter

这些数组方法,它们提供了极大的灵活性,开发者可以通过组合它们来解决各种复杂问题,包括分组。

当然,社区也一直有声音呼吁添加更直接的

groupBy

方法。实际上,现在ECMAScript提案中已经有了

Object.groupBy

Map.groupBy

,它们目前处于Stage 3阶段,这意味着它们很有可能被纳入未来的JavaScript标准。这表明了语言也在不断演进,吸纳社区的实际需求。不过在那之前,我们还是得依赖像

reduce

这样的“老兵”来完成任务。我个人觉得,虽然多写几行代码,但用

reduce

实现的分组逻辑,其透明度和可控性还是挺不错的。

使用

map

对象实现更灵活的分组

前面我们用的是一个普通JavaScript对象作为累加器,它的键默认会被转换为字符串。但在某些场景下,你可能需要用非字符串类型(比如一个对象实例或一个数字)作为分组的键。这时,使用

map

对象作为累加器会是更好的选择,因为它允许任何类型的值作为键。

const products = [  { id: 101, name: 'Laptop', category: { id: 'elec', name: 'Electronics' } },  { id: 102, name: 'Mouse', category: { id: 'elec', name: 'Electronics' } },  { id: 103, name: 'Shirt', category: { id: 'cloth', name: 'Apparel' } },  { id: 104, name: 'Keyboard', category: { id: 'elec', name: 'Electronics' } },];// 根据 category 对象进行分组const groupedByCategory = products.reduce((acc, product) => {  // 这里我们将整个 category 对象作为键  // 注意:如果 category 是不同的对象实例但内容相同,Map会视为不同的键  // 实际应用中,你可能需要一个稳定的、可比较的键,比如 category.id  const key = product.category.id; // 或者直接用 product.category 如果你确定是同一个引用  if (!acc.has(key)) {    acc.set(key, []);  }  acc.get(key).push(product);  return acc;}, new Map()); // 初始累加器是一个新的Map对象console.log(groupedByCategory);/*输出大致结构(Map对象):Map(2) {  'elec' => [    { id: 101, name: 'Laptop', category: { id: 'elec', name: 'Electronics' } },    { id: 102, name: 'Mouse', category: { id: 'elec', name: 'Electronics' } },    { id: 104, name: 'Keyboard', category: { id: 'elec', name: 'Electronics' } }  ],  'cloth' => [    { id: 103, name: 'Shirt', category: { id: 'cloth', name: 'Apparel' } }  ]}*/

使用

map

的好处在于,它能更好地处理非字符串键,并且在迭代时能保持插入顺序。对于大型数据集,

map

在某些操作上可能会有更好的性能表现,因为它不是基于哈希表的普通对象,而是专门为键值对存储优化的。

借助Lodash等实用工具

在许多实际的项目中,为了代码的简洁性、健壮性和性能,开发者经常会引入一些成熟的工具库。其中,Lodash就是非常受欢迎的一个,它提供了大量实用的功能函数,包括一个非常方便的

_.groupBy

// 假设你已经通过 npm/yarn 安装并导入了 lodash// import _ from 'lodash';const students = [  { name: 'Alice', grade: 'A' },  { name: 'Bob', grade: 'B' },  { name: 'Charlie', grade: 'A' },  { name: 'David', grade: 'C' },];// 使用 Lodash 的 groupBy// 注意:这里需要引入 Lodash 库才能运行// const groupedByGrade = _.groupBy(students, 'grade');// 如果不使用外部库,这里只是一个概念性的展示// 它的内部实现原理和我们用 reduce 写的类似,但更优化和通用/*理论上 Lodash 的输出会是这样:{  "A": [    { name: 'Alice', grade: 'A' },    { name: 'Charlie', grade: 'A' }  ],  "B": [    { name: 'Bob', grade: 'B' }  ],  "C": [    { name: 'David', grade: 'C' }  ]}*/

Lodash的

groupBy

方法非常直观,你只需要传入数组和用于分组的属性名(或一个函数)。它能自动处理很多边缘情况,并且经过了性能优化。在企业级应用开发中,引入这样的库通常是标准实践,因为它能显著减少样板代码,并提高开发效率和代码的可维护性。当然,如果项目对依赖包大小有严格要求,或者功能需求非常简单,自己用

reduce

实现也完全可行。选择哪种方式,很多时候取决于项目的具体上下文和团队的偏好。

以上就是js 如何使用groupBy对对象数组进行分组的详细内容,更多请关注创想鸟其它相关文章!

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

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
什么是JIT编译?JIT的工作原理
上一篇 2025年12月20日 09:39:38
js怎么获取表单输入的值
下一篇 2025年12月20日 09:39:47

相关推荐

  • 如何解决PHP8字符串与数字比较的陷阱,使用Psalm插件确保代码平稳升级

    Composer在线学习地址:学习地址 最近,我们团队计划将一个运行多年的老项目从 php 7 升级到 php 8。起初,我们信心满满,认为只要处理好一些明显的语法变动和废弃功能,升级就会一帆风顺。然而,很快我们就遇到了一个让人头疼的“隐形杀手”:php 8 对字符串和数字的比较逻辑进行了调整。 在…

    用户投稿 2026年8月25日
    000
  • 音频格式转换方法

    音频格式转换方法音频格式转换方法音频格式转换方法音频格式转换方法

    当遇到音频格式不兼容的情况时,可以通过使用格式转换工具将文件转换为设备或软件支持的格式。 1、 打开格式工厂软件 2、 在软件左侧列表中选择音频类型,点击后选择目标格式(例如WMA),准备进行转换。 3、 添加需要转换的文件,并设置输出文件的保存路径。 4、 浏览并定位到原始音频文件所在的存储位置。…

    2026年8月25日 用户投稿
    100
  • MiaoLab妙莱安全插排:以创新安全与美学设计,重塑用电新体验

    MiaoLab妙莱安全插排:以创新安全与美学设计,重塑用电新体验MiaoLab妙莱安全插排:以创新安全与美学设计,重塑用电新体验MiaoLab妙莱安全插排:以创新安全与美学设计,重塑用电新体验MiaoLab妙莱安全插排:以创新安全与美学设计,重塑用电新体验

    在国民安全意识持续提升、家居审美需求日益增长的当下,家庭用电安全已然成为衡量“高品质生活”的重要标准。传统插排普遍存在设计简陋、重心偏高、插孔位置过低等问题,常被视作“安全隐患源头”和“桌面杂乱罪魁”。miaolab妙莱作为新兴的生活方式品牌,敏锐洞察这一用户痛点,推出全球首款不倒翁结构安全插排,以…

    2026年8月25日 用户投稿
    000
  • 更强大的PHP反射!wingu/reflection如何解决复杂类型分析难题

    在大型PHP项目中,类型信息的准确性和完整性至关重要。例如,在使用依赖注入容器时,我们需要准确地知道构造函数的参数类型,才能正确地注入依赖。又或者,在进行代码生成时,我们需要从DocBlock中提取信息,生成相应的代码。PHP原生的反射API在处理这些场景时,往往需要编写大量的代码,而且容易出错。 …

    用户投稿 2026年8月25日
    100
  • 电脑wifi连接不上怎么解决 6招轻松搞定

    电脑wifi连接不上怎么解决 6招轻松搞定电脑wifi连接不上怎么解决 6招轻松搞定电脑wifi连接不上怎么解决 6招轻松搞定电脑wifi连接不上怎么解决 6招轻松搞定

    有时候电脑无法连接wifi,确实会让人感到非常烦恼。实际上,造成wifi连接失败的原因多种多样,只要按步骤逐一排查,大多数问题都能迅速解决。接下来,我们就来系统地分析一下电脑连不上wifi的常见原因及对应的解决办法。 一、确认无线功能是否启用 首先应检查电脑的WiFi功能是否开启。部分笔记本电脑配备…

    2026年8月25日 用户投稿
    200
  • Java中如何实现链路追踪 掌握Sleuth

    Java中如何实现链路追踪 掌握SleuthJava中如何实现链路追踪 掌握SleuthJava中如何实现链路追踪 掌握SleuthJava中如何实现链路追踪 掌握Sleuth

    如何在spring boot项目中集成sleuth?首先,在pom.xml中添加sleuth依赖:spring-cloud-starter-sleuth;其次,如需对接zipkin,添加spring-cloud-sleuth-zipkin依赖;然后,在配置文件中设置zipkin服务器地址和应用名称。…

    2026年8月25日 用户投稿
    000
  • 硬件监控软件横评:HWiNFO64、AIDA64、CPU-Z 功能对比

    CPU-Z适合快速查看硬件配置,AIDA64提供全面信息与压力测试,HWiNFO64则以深度传感器数据成为专业监控首选,三者各有侧重,按需选用。 说到看电脑硬件信息和监控状态,HWiNFO64、AIDA64和CPU-Z是很多人会用的工具。它们都能告诉你电脑里有什么,但侧重点和功能深度差别不小。简单说…

    2026年8月25日
    100
  • Java中IoC是什么概念 图解控制反转和依赖注入的实现原理

    Java中IoC是什么概念 图解控制反转和依赖注入的实现原理Java中IoC是什么概念 图解控制反转和依赖注入的实现原理Java中IoC是什么概念 图解控制反转和依赖注入的实现原理Java中IoC是什么概念 图解控制反转和依赖注入的实现原理

    ioc反转的是对象的控制权。传统开发中对象自己管理依赖,而ioc将对象创建和依赖管理交给外部容器,从而实现控制权的反转。ioc是一种设计原则,di是其具体实现方式,通过构造器、setter或接口注入依赖。java中依赖注入主要有三种方式:1.构造器注入,通过构造函数传递依赖,优点是依赖明确且不可变;…

    2026年8月25日 用户投稿
    000
  • java中的field有什么用 字段field的3个访问控制技巧

    java中的field有什么用 字段field的3个访问控制技巧java中的field有什么用 字段field的3个访问控制技巧java中的field有什么用 字段field的3个访问控制技巧java中的field有什么用 字段field的3个访问控制技巧

    java中的field主要用于反射,允许运行时检查和修改类的字段,包括私有字段。具体步骤如下:1. 获取class对象后,使用getfield()或getdeclaredfield()获取field对象,前者用于获取public字段(包括继承的),后者用于获取本类声明的所有字段;2. 使用setac…

    2026年8月25日 用户投稿
    000
  • 云原生(Kubernetes)适配进展

    kubernetes的适配进展主要体现在:1) 生态系统的扩展,涌现了如istio和linkerd等工具;2) 与云服务的集成,如gke和eks的托管服务;3) 对新兴技术的支持,如knative的无服务器平台。尽管面临复杂性和安全性挑战,kubernetes仍是云原生技术的领导者。 云原生(Kub…

    2026年8月25日
    000
  • 抖音可以添加什么小程序

    抖音支持接入多种类型的小程序,涵盖电商、游戏、教育、工具等多个领域,让用户在不离开应用的情况下即可完成购物、娱乐、学习和日常事务处理。本文将全面解析抖音可添加的小程序类别及其核心功能,助力用户更高效地使用平台资源。 电商类小程序电商类小程序在抖音生态中占据重要地位,极大提升了内容与消费之间的转化效率…

    2026年8月25日
    000
  • 悟空搜索能搜到公共交通_悟空搜索出行路线规划技巧

    答案是未正确使用查询功能。需在悟空搜索输入起点终点并添加“公交”等关键词,更新应用、开启定位,进入出行标签后选择公交模式,再通过地图视图查看实时信息。 如果您尝试使用悟空搜索查询出行路线,但未能获取公共交通信息,可能是由于查询方式或功能设置未正确使用。以下是解决此问题的步骤: 一、确认搜索关键词与功…

    2026年8月25日
    000
  • Java中锁的分类有哪些 详解Java中的各种锁机制

    Java中锁的分类有哪些 详解Java中的各种锁机制Java中锁的分类有哪些 详解Java中的各种锁机制Java中锁的分类有哪些 详解Java中的各种锁机制Java中锁的分类有哪些 详解Java中的各种锁机制

    java中的锁主要分为悲观锁与乐观锁、公平锁与非公平锁、可重入锁与不可重入锁、独占锁与共享锁等类型。1.悲观锁如synchronized和reentrantlock适用于写多场景,每次操作都加锁保证数据一致性;2.乐观锁通过版本号或cas实现,适用于读多写少的场景,提高吞吐量;3.公平锁按申请顺序获…

    2026年8月25日 用户投稿
    100
  • 电脑提示DirectX错误导致玩不了游戏怎么办 4种实用方法

    电脑提示DirectX错误导致玩不了游戏怎么办 4种实用方法电脑提示DirectX错误导致玩不了游戏怎么办 4种实用方法电脑提示DirectX错误导致玩不了游戏怎么办 4种实用方法电脑提示DirectX错误导致玩不了游戏怎么办 4种实用方法

    directx是windows平台上运行游戏和图形应用的关键技术组件。当启动游戏时出现“directx错误”“缺少dx11/12”等提示,可能导致程序闪退、画面异常或无法正常运行。以下是几种有效的解决方式。 方法1:更新或修复DirectX组件 DirectX 12等新版组件通常随系统更新一并发布。…

    2026年8月25日 用户投稿
    000
  • 高德地图App如何模拟导航功能 高德地图App提前熟悉路况的练习方法

    可通过高德地图模拟导航预演行车路线。在iPhone 15 Pro上打开高德地图,搜索目的地后点击开始导航进入界面,上滑调出工具栏并点击模拟导航图标即可启动;也可在路线规划页输入起终点后上滑点击播放图标快速模拟;模拟过程中可调节0.5至2倍速或暂停分段练习。 如果您想在出发前预演行车路线,避免实际驾驶…

    2026年8月25日
    100
  • 如何在Laravel应用中快速集成用户消息系统?使用cmgmyr/messenger轻松实现!

    可以通过一下地址学习composer:学习地址 告别从零开始的痛苦:Laravel 消息系统开发的挑战 想象一下,你正在开发一个社交平台或一个团队协作工具,用户之间需要进行私聊、群聊,甚至多方会话。如果你决定从头开始构建这个消息系统,你很快就会发现这远比想象中复杂: 数据库设计: 如何存储会话(Th…

    用户投稿 2026年8月25日
    000
  • 空中版高德地图“空中高德”发布,低空飞行器也能用导航

    感谢网友 sp_ce 提供的线索! 7 月 30 日讯,由龙岗区人民政府携手高德软件有限公司共同主办的“空中高德・龙岗启航”—— 深圳市龙岗区空中高德时空底座发布会今日在香港中文大学(深圳)隆重召开。标志着覆盖全业务场景的低空经济示范项目——“空中高德”在龙岗正式落地启动。 据高德地图官方消息,作为…

    2026年8月25日
    000
  • 作业帮如何查找同类型题目练习_作业帮同类型题目练习指南

    想在作业帮上找到同类型的数学题来巩固练习,关键在于用好它的智能搜索和系统化学习功能。直接拍题搜答案只是第一步,真正提分要靠对同类题型的归纳和训练。下面这几个方法结合使用效果最好。 拍照搜题后查看“同类题”推荐 这是最直接的方式。打开作业帮App,使用首页的“拍照搜题”功能,清晰拍摄你遇到的题目。识别…

    2026年8月25日
    000
  • 电脑屏幕分辨率怎么调 快速设置指南

    电脑屏幕分辨率怎么调 快速设置指南电脑屏幕分辨率怎么调 快速设置指南电脑屏幕分辨率怎么调 快速设置指南电脑屏幕分辨率怎么调 快速设置指南

    合适的分辨率能带来更清晰、细腻的视觉体验,有助于提升工作效率或增强游戏沉浸感。但如果分辨率设置不合理,可能会造成画面模糊、比例异常等问题。本文将详细讲解如何正确调整电脑屏幕分辨率,并分享一些关键的注意事项。 一、屏幕分辨率的基本概念 屏幕分辨率指的是屏幕上显示的像素总数,通常以“横向像素×纵向像素”…

    2026年8月25日 用户投稿
    000
  • 大型综合商城商城与抖音合作的有哪些

    近年来,越来越多的大型综合商城选择与抖音这一热门社交平台联手,借助短视频内容吸引更多消费者关注。这种跨界合作实现了资源互补和互利共赢:商城获得更广泛的流量入口和品牌曝光机会,而抖音则通过引入优质商业内容增强平台生态活力。接下来,本文将深入剖析几个典型合作案例,并探讨此类合作背后的深层价值。 大型综合…

    2026年8月25日
    000

发表回复

登录后才能评论
关注微信