JavaScript中新数组分组方法详解

2024-03-01 0 598
目录
  • 以前的做法
  • 使用Object.groupBy
  • 使用Map.groupBy
  • 何时可用
  • 为什么使用静态方法
  • 总结

对数组中的项目进行分组,你可能已经做过很多次了。每次都会手动编写一个分组函数,或者使用lodash的groupBy函数。

好消息是,JavaScript 现在有了分组方法,所以你再也不必这样做了。Object.groupBy和Map.groupBy这两个新方法将使分组变得更简单,并节省我们的时间或依赖性。

以前的做法

假设你有一个代表人的对象数组,你想按年龄对它们进行分组。你可以这样使用forEach循环:

const people = [
{ name: \”Alice\”, age: 28 },
{ name: \”Bob\”, age: 30 },
{ name: \”Eve\”, age: 28 },
];

const peopleByAge = {};

people.forEach((person) => {
const age = person.age;
if (!peopleByAge[age]) {
peopleByAge[age] = [];
}
peopleByAge[age].push(person);
});
console.log(peopleByAge);
/*
{
\”28\”: [{\”name\”:\”Alice\”,\”age\”:28}, {\”name\”:\”Eve\”,\”age\”:28}],
\”30\”: [{\”name\”:\”Bob\”,\”age\”:30}]
}
*/

或者可以像这样来使用reduce:

const peopleByAge = people.reduce((acc, person) => {
const age = person.age;
if (!acc[age]) {
acc[age] = [];
}
acc[age].push(person);
return acc;
}, {});

无论哪种方法,代码都略显笨拙。你总是要检查对象是否存在分组键,如果不存在,就用一个空数组来创建它。然后再将项目推入数组。

使用Object.groupBy

有了新的Object.groupBy方法,你就可以像这样得出结果:

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

简单多了!不过也有一些需要注意的地方。

Object.groupBy返回一个空原型对象。这意味着该对象不继承Object.prototype的任何属性。这很好,因为这意味着你不会意外覆盖Object.prototype上的任何属性,但这也意味着该对象没有你可能期望的任何方法,如hasOwnProperty或toString。

const peopleByAge = Object.groupBy(people, (person) => person.age);
console.log(peopleByAge.hasOwnProperty(\”28\”));
// TypeError: peopleByAge.hasOwnProperty is not a function

传递给Object.groupBy的回调函数应返回字符串或Symbol。如果返回其他内容,则将强制转为字符串。

在我们的示例中,我们一直以数字形式返回age,但在结果中却被强制转为字符串。尽管如此,你仍然可以使用数字访问属性,因为使用方括号符号也会将参数强制为字符串。

console.log(peopleByAge[28]);
// => [{\”name\”:\”Alice\”,\”age\”:28}, {\”name\”:\”Eve\”,\”age\”:28}]
console.log(peopleByAge[\”28\”]);
// => [{\”name\”:\”Alice\”,\”age\”:28}, {\”name\”:\”Eve\”,\”age\”:28}]

使用Map.groupBy

除了返回Map之外,Map.groupBy的功能与Object.groupBy几乎相同。这意味着你可以使用所有常用的Map函数。这也意味着你可以从回调函数返回任何类型的值。

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 中按对象检索项目,对象必须具有相同的引用。

peopleByManager.get(ceo);
// => [{ name: \”Alice\”, age: 28, reportsTo: ceo }, { name: \”Eve\”, age: 28, reportsTo: ceo }]
peopleByManager.get({ name: \”Jamie\”, age: 40, reportsTo: null });
// => undefined

在上面的示例中,第二行使用了一个看起来像ceo对象的对象,但它并不是同一个对象,因此它不会从Map中返回任何内容。要想成功地从Map中获取项目,请确保你保留了要用作键的对象的引用。

何时可用

这两个groupBy方法是 TC39 提议的一部分,目前处于第三阶段。这意味着它很有可能成为一项标准,因此也出现了一些实施方案。

Chrome 浏览器 117 版本刚刚推出了对这两种方法的支持,而 Firefox 浏览器 119 版本也发布了对这两种方法的支持。Safari 以不同的名称实现了这些方法,我相信他们很快就会更新。既然 Chrome 浏览器中出现了这些方法,就意味着它们已在 V8 中实现,因此下次 V8 更新时,Node 中也会出现这些方法。

为什么使用静态方法

你可能会问,为什么要以Object.groupBy而不是Array.prototype.groupBy的形式来实现呢?根据该提案,有一个库曾经用一个不兼容的groupBy方法对Array.prototype进行了猴子补丁。在考虑新的应用程序接口时,向后兼容性非常重要。几年前,在尝试实现Array.prototype.flatten时,这一点在一次被称为SmooshGate的事件中得到了强调。

幸运的是,使用静态方法似乎更有利于未来的可扩展性。当 Record 和 Tuples 提议实现时,我们可以添加一个Record.groupBy 方法,用于将数组分组为不可变的记录。

总结

将项目分组显然是我们开发人员的一项重要工作。目前,每周从 npm 下载lodash.groupBy的次数在 150 万到 200 万之间。很高兴看到 JavaScript 填补了这些空白,让我们的工作变得更加轻松。

现在,下载 Chrome 117 并亲自尝试这些新方法吧。

到此这篇关于JavaScript中新数组分组方法详解的文章就介绍到这了,更多相关JavaScript数组分组内容请搜索悠久资源网以前的文章或继续浏览下面的相关文章希望大家以后多多支持悠久资源网!

您可能感兴趣的文章:

  • JavaScript中实现数组分组功能的方法详解
  • JavaScript数组中相同的元素进行分组(数据聚合)groupBy函数详解
  • JavaScript数组分组groupBy示例详解
  • JavaScript如何实现数组按属性分组
  • javascript数组按属性分组实现方法
  • js实现json数组分组合并操作示例

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 JavaScript JavaScript中新数组分组方法详解 https://www.u-9.cn/biancheng/javascript/182274.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务