Javascript支持数组分组(groupBy)的方法即将到来!

前言

JavaScript编程中,对数组进行分组是一项常见的任务。无论是根据特定属性将对象分组,还是按照某些规则重新组织数组元素,分组操作在日常开发中都是常见的。过去,为了实现这一目标,通常需要编写自定义的分组函数或者使用第三方库,比如lodashgroupBy函数。然而,好消息是,JavaScript正逐渐引入原生的分组方法,使我们的开发工作更加便捷。在本文中,我们将探讨JavaScript的新特性,即Object.groupByMap.groupBy,这两个新特性将使数组分组操作更加容易。

分组操作的背景

假设现在有一个包含人员信息的数组,每个人都有姓名和年龄属性,需求想要按照他们的年龄将他们分组。在以前的JavaScript中,可能需要编写自定义的分组函数,或者使用forEachreduce等方法,来实现分组操作。如下:

ini 复制代码
const people = [
  { name: "Alice", age: 28 },
  { name: "Bob", age: 30 },
  { name: "Eve", age: 28 },
];

// 使用forEach进行分组
const peopleByAge = {};

people.forEach((person) => {
  const age = person.age;
  if (!peopleByAge[age]) {
    peopleByAge[age] = [];
  }
  peopleByAge[age].push(person);
});

// 使用reduce进行分组
const peopleByAge = people.reduce((acc, person) => {
  const age = person.age;
  if (!acc[age]) {
    acc[age] = [];
  }
  acc[age].push(person);
  return acc;
}, {});
 

运行结果:

无论是使用forEach还是reduce,这些传统方法都需要手动检查分组键是否存在,如果不存在则创建一个空数组,然后将对象推入该数组中。上面的示例代码相对繁琐,可能需要不少工作量,尤其是在复杂的应用程序中。

下面就来Javascript即将支持的两种新特性是如何实现上述需求的→

Object.groupBy:原生分组方法

JavaScript新引入的Object.groupBy方法,使数据分组将变得更加简单和高效。使用Object.groupBy,可以按照指定的属性或规则将数组中的对象分组,而不需要手动管理分组过程。如下:

ini 复制代码
const people = [
  { name: "Alice", age: 28 },
  { name: "Bob", age: 30 },
  { name: "Eve", age: 28 },
];

const peopleByAge = Object.groupBy(people, (person) => person.age);

在控制台运行代码可以看到:

如上图所示,使用Object.groupBy,只需提供一个回调函数,该回调函数将确定如何进行分组。在这种情况下,就可以按照人的年龄属性进行分组,这是不是比传统的手动分组方法要简单得多。

然而,需要注意的是,Object.groupBy返回一个无原型的对象,这意味着它不会继承Object.prototype上的任何属性或方法。因此,不能像通常那样使用hasOwnProperty等方法。此外,回调函数应返回一个字符串或符号,否则它将被强制转换为字符串。

arduino 复制代码
console.log(peopleByAge.hasOwnProperty("28"));

Map.groupBy:返回Map对象的分组方法

除了Object.groupByJavaScript还引入了Map.groupBy方法,该方法在执行分组操作时返回一个Map对象。与Object.groupBy相比,Map.groupBy提供了更多的灵活性,因为它允许返回任何类型的值,并且可以使用Map的各种方法来操作结果。如下:

ini 复制代码
const ceo = { name: "Jamie", age: 40, reportsTo: null };
const manager = { name: "Alice", age: 28, reportsTo: ceo };

const people = [
  ceo,
  manager,
  { name: "Bob", age: 30, reportsTo: manager },
  { name: "Eve", age: 28, reportsTo: ceo },
];

const peopleByManager = Map.groupBy(people, (person) => person.reportsTo); 

运行结果:

在这个示例中,我们根据人员的上级进行分组。一个重要的注意点是,要从Map中检索对象,必须使用相同的对象引用。如果传递的对象虽然内容相同但不是同一个对象,将无法从Map中检索到结果。

php 复制代码
peopleByManager.get(ceo); // 返回与ceo对象相关的人员
peopleByManager.get({ name: "Jamie", age: 40, reportsTo: null }); // 返回undefined,因为这不是同一个对象

Map.groupBy的优势在于,它返回一个Map对象,可以使用Map的方法来处理分组后的结果,这在某些场景下非常有用。

分组方法的兼容性

目前Object.groupByMap.groupByTC39 提案的一部分,目前处于第3 阶段。这表明它们有望成为JavaScript标准的一部分。在实际应用中,Chrome 117已经支持这两个方法,而Firefox Nightly则在实验标志下实现了它们。Safari也已经实现了类似的方法,可以期待它们会在不久的将来更新以提供更好的支持。

上面示例代码运行的浏览器版本是118.0.5993.89,故可以正确的打印出结果。

疑问

你可能会疑惑为什么这些分组方法被实现为Object.groupByMap.groupBy,而不是Array.prototype.groupBy。这是因为在过去,有一些库曾经在Array.prototype上添加了不兼容的groupBy方法,这导致了一些兼容性问题,所以就没有在在Array.prototype上实现。

总结

本文介绍了JavaScript中即将引入的Object.groupByMap.groupBy两种原生分组方法的使用。这些两种原生分组方法将填补JavaScript开发中的空白,使前端开发人员能够更轻松地进行分组操作,提高了编程效率和代码质量。希望本文能对你以后的工作有所帮助。

后语

小伙伴们,如果觉得本文对你有些许帮助,点个👍或者➕个关注再走吧^_^ 。另外如果本文章有问题或有不理解的部分,欢迎大家在评论区评论指出,我们一起讨论共勉。

相关推荐
dr李四维9 分钟前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
I_Am_Me_23 分钟前
【JavaEE进阶】 JavaScript
开发语言·javascript·ecmascript
雯0609~30 分钟前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ34 分钟前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z39 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
前端百草阁1 小时前
【TS简单上手,快速入门教程】————适合零基础
javascript·typescript
彭世瑜1 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4041 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish1 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
zwjapple1 小时前
typescript里面正则的使用
开发语言·javascript·正则表达式