ES2024新特性:object.groupBy()让分组更简单

dd8efb8d16d91cad4f508e96c3856f7b.png

2024年初,JavaScript(也称为Ecma Script)推出了一项全新的内置函数——object.groupBy()。这一创新功能将彻底改变我们对数据进行分组和组织的方式!

什么是object.groupBy()?

复杂定义:

object.groupBy()是一个静态方法,允许你基于提供的回调函数对可迭代对象(如数组)中的元素进行分组。最终会生成一个新的对象,该对象的每个属性都是一个组,每个组中包含属于该组的元素数组。

简单定义:

它是一个可以按任何你希望的方式对数组进行分类和排序的函数,就像是你数据的私人整理员,确保一切都被整齐地分类和轻松访问。

值得一提的是,如果你需要使用任意值(不仅仅是字符串)来进行分组,Map.groupBy()函数也能帮你搞定。

语法和参数

在深入了解object.groupBy()之前,让我们先熟悉一下它的语法和参数:

Object.groupBy(items, callbackFn)
  • items:一个可迭代对象(如数组),包含你想要分组的元素。

  • callbackFn:一个回调函数,对每个元素执行。这个函数应该返回一个可以转换为属性键(字符串或符号)的值,指示当前元素所属的组。

回调函数callbackFn的参数包括:

  • element:当前正在处理的元素。

  • index:当前正在处理的元素的索引。

返回值

object.groupBy()函数返回一个无原型的对象,该对象的每个属性都是一个组,每个组分配给包含相关组元素的数组。就像一个精心组织的文件柜,为你的数据提供完美的分类和管理。

示例

示例1:按类别分组库存

假设你在经营一家杂货店,需要根据食物类别来组织库存。有了object.groupBy(),这个任务变得轻而易举:

const inventory = [
 { name: "asparagus", type: "vegetables", quantity: 5 },
 { name: "bananas", type: "fruit", quantity: 0 },
 { name: "goat", type: "meat", quantity: 23 },
 { name: "cherries", type: "fruit", quantity: 5 },
 { name: "fish", type: "meat", quantity: 22 },
];

const result = Object.groupBy(inventory, ({ type }) => type);

/* 结果如下:
{
 vegetables: [
 { name: "asparagus", type: "vegetables", quantity: 5 },
 ],
 fruit: [
 { name: "bananas", type: "fruit", quantity: 0 },
 { name: "cherries", type: "fruit", quantity: 5 }
 ],
 meat: [
 { name: "goat", type: "meat", quantity: 23 },
 { name: "fish", type: "meat", quantity: 22 }
 ]
}
*/

在这个示例中,我们定义了一个包含不同食物项目的数组inventory。通过调用Object.groupBy(inventory, ({ type }) => type),我们根据食物的type属性对元素进行分组,并得到一个按类别(蔬菜、水果、肉类)组织的对象,每个类别都包含一个对应项目的数组。

示例2:基于多个条件分组

如果你需要根据多个条件对数据进行分组,object.groupBy()同样能满足需求:

const students = [
 { name: "Alice", grade: 9, subject: "Math" },
 { name: "Bob", grade: 10, subject: "Science" },
 { name: "Charlie", grade: 9, subject: "English" },
 { name: "David", grade: 10, subject: "Math" },
 { name: "Eve", grade: 9, subject: "Science" },
];

const result = Object.groupBy(students, ({ grade, subject }) => `${grade}-${subject}`);

/* 结果如下:
{
 "9-Math": [
 { name: "Alice", grade: 9, subject: "Math" }
 ],
 "10-Science": [
 { name: "Bob", grade: 10, subject: "Science" }
 ],
 "9-English": [
 { name: "Charlie", grade: 9, subject: "English" }
 ],
 "10-Math": [
 { name: "David", grade: 10, subject: "Math" }
 ],
 "9-Science": [
 { name: "Eve", grade: 9, subject: "Science" }
 ]
}
*/

在这个示例中,我们有一个学生对象数组,每个学生都有姓名、年级和科目。通过使用回调函数({ grade, subject }) => {subject}``,我们根据年级和科目的组合对学生进行分组,结果是一个表示每个唯一组合的对象,每个组合包含相应学生的数组。

示例3:基于自定义条件分组

object.groupBy()的真正威力在于它能够基于自定义条件对数据进行分组。假设你经营一个电商网站,想根据产品的可用性来分组:

const products = [
 { name: "Product A", price: 10, inStock: true },
 { name: "Product B", price: 20, inStock: false },
 { name: "Product C", price: 15, inStock: true },
 { name: "Product D", price: 25, inStock: false },
 { name: "Product E", price: 18, inStock: true },
];

function myCallback({ inStock }) {
 return inStock ? "available" : "outOfStock";
}

const result = Object.groupBy(products, myCallback);

/* 结果如下:
{
 available: [
 { name: "Product A", price: 10, inStock: true },
 { name: "Product C", price: 15, inStock: true },
 { name: "Product E", price: 18, inStock: true }
 ],
 outOfStock: [
 { name: "Product B", price: 20, inStock: false },
 { name: "Product D", price: 25, inStock: false }
 ]
}
*/

在这个示例中,我们定义了一个包含产品对象的数组,每个产品都有名称、价格和库存状态。然后,我们创建了一个自定义回调函数myCallback,根据inStock属性返回“available”或“outOfStock”。通过传递这个回调函数给Object.groupBy(products, myCallback),我们将产品分为两个类别:“available”和“outOfStock”,结果是一个包含两个属性的对象,每个属性包含相应产品的数组。

结束

如你所见,object.groupBy()函数非常强大!无论你是在处理简单还是复杂的数据结构,这个函数都可以根据你能想到的几乎任何条件对数据进行分组。

这些例子仅仅是冰山一角。通过一些创造力和巧妙的回调函数,你可以实现更多功能。想象一下,基于复杂计算、正则表达式甚至外部数据源对数据进行分组——可能性是无穷无尽的!

### JavaScript 中 Object GroupBy 方法及其替代方案 在 ECMAScript 2023 (ES14) 及高版本中引入了 `Array.prototype.group` 和 `Array.prototype.groupToMap` 方法,这些方法可以实现类似于 SQL 的 GROUP BY 功能[^2]。 对于较旧环境中的开发者来说,在 ES14 推出之前并没有内置的 `group by` 函数可以直接作用于对象或者数组。因此通常会采用其他方式来达到分组的目的: #### 使用 reduce 实现自定义 groupBy 方法 一种常见的做法是利用 `reduce()` 来创建自己的 `groupBy` 辅助函数: ```javascript function groupBy(array, keySelector) { return array.reduce((result, currentValue) => { const key = typeof keySelector === 'function' ? keySelector(currentValue) : currentValue[keySelector]; if (!result[key]) result[key] = []; result[key].push(currentValue); return result; }, {}); } ``` 此代码片段展示了如何通过传入一个键选择器参数(可以是一个属性名字符串或者是返回所需键值的回调函数),从而对给定的数据集按照指定条件进行分类汇总[^3]。 #### 利用第三方库 lodash 或 underscore.js 提供的功能 除了自己编写工具函数外,还可以借助像 Lodash 这样的流行实用程序库所提供的现成解决方案。Lodash 提供了一个非常方便的方法叫做 _.groupBy() ,它能够接受两个参数:一个是待处理集合;另一个是用来决定怎样划分数据项的标准表达式或字段名称。 ```javascript const _ = require('lodash'); let users = [ { user: 'barney', age: 36 }, { user: 'fred', age: 40 }, { user: 'pebbles', age: 1 } ]; _.groupBy(users, 'age'); // 返回按年龄分组的对象结构 // → { '36': [{ user: 'barney', age: 36 }], '40': [{ user: 'fred', age: 40 }], '1': [{ user: 'pebbles', age: 1 }] } ``` 这种方法不仅简洁明了而且性能优越,适合快速开发需求下的应用场合[^4]。 #### 应用场景举例说明 假设有一个包含多个学生记录的学生列表,想要根据年级对学生进行分组,则可如下操作: ```javascript const students = [ {"name": "Alice", grade: 7}, {"name": "Bob", grade: 8}, {"name": "Charlie", grade: 7}, ... ] // 自定义 groupBy 方案 console.log(groupBy(students, student => student.grade)); /* 输出结果形似: { 7: [{"name":"Alice","grade":7},{"name":"Charlie","grade":7}], 8: [{"name":"Bob","grade":8}] } */ ``` 上述例子演示了当面对不同编程环境下缺乏原生支持的情况时,可以通过多种途径有效地完成类似的分组逻辑[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值