Object.groupBy()

Baseline 2024

Newly available

Since March 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

实验性: 这是一项实验性技术
在将其用于生产之前,请仔细检查浏览器兼容性表格

备注: 在某些浏览器的某些版本中,此方法被实现为 Array.prototype.group() 方法。由于 web 兼容性问题,它现在以静态方法实现。参见浏览器兼容性表格以获取更多信息。

Object.groupBy() 静态方法根据提供的回调函数返回的字符串值对给定可迭代对象中的元素进行分组。返回的对象具有每个组的单独属性,其中包含组中的元素的数组。

当分组名称可以用字符串表示时,应使用此方法。如果你需要使用某个任意值作为键来对元素进行分组,请改用 Map.groupBy() 方法。

语法

js
Object.groupBy(items, callbackFn)

参数

items

一个将进行元素分组的可迭代对象(例如 Array)。

callbackFn

对可迭代对象中的每个元素执行的函数。它应该返回一个值,可以被强制转换成属性键(字符串或 symbol),用于指示当前元素所属的分组。该函数被调用时将传入以下参数:

element

数组中当前正在处理的元素。

index

正在处理的元素在数组中的索引。

返回值

一个带有所有分组属性的 null 原型对象,每个属性都分配了一个包含相关组元素的数组。

描述

Object.groupBy() 为可迭代对象中的每个元素调用一次提供的 callbackFn 函数。回调函数应返回一个字符串或 symbol(不属于这两种类型的值会被强制转换为字符串),用于指示元素所属的分组。callbackFn 的返回值会被用作 Map.groupBy() 返回的对象的键。每个键都有一个相关联的数组,其中包含回调函数返回相同值的所有元素。

返回的对象中的元素和原始可迭代对象中的元素相同(不是深拷贝)。更改元素的内部结构将反映在原始可迭代对象和返回的对象中。

示例

使用 Object.groupBy()

首先,我们定义一个包含代表各种食品库存的对象的数组。每种食品都有一个 type 和一个 quantity 属性。

js
const inventory = [
  { name: "芦笋", type: "蔬菜", quantity: 5 },
  { name: "香蕉", type: "水果", quantity: 0 },
  { name: "山羊", type: "肉", quantity: 23 },
  { name: "樱桃", type: "水果", quantity: 5 },
  { name: "鱼", type: "肉", quantity: 22 },
];

下面的代码根据元素的 type 属性的值对元素进行分组。

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

/* 结果是:
{
  蔬菜: [
    { name: "芦笋", type: "蔬菜", quantity: 5 },
  ],
  水果: [
    { name: "香蕉", type: "水果", quantity: 0 },
    { name: "樱桃", type: "水果", quantity: 5 }
  ],
  肉: [
    { name: "山羊", type: "肉", quantity: 23 },
    { name: "鱼", type: "肉", quantity: 22 }
  ]
}
*/

箭头函数每次被调用时都只返回每个数组元素的 type 属性。请注意,函数参数 { type } 是一个函数参数的对象解构语法的基本示例。这会解构传递为参数的对象的 type 属性,并将其赋值给函数体中名为 type 的变量。这是一种非常简洁的访问函数中相关元素的值的方式。

我们还可以创建根据元素的一个或多个属性中的值推断的分组。下面是一个非常类似的示例,根据 quantity 字段的值将项目分为 okrestock 组。

js
function myCallback({ quantity }) {
  return quantity > 5 ? "ok" : "restock";
}

const result2 = Object.groupBy(inventory, myCallback);

/* 结果是:
{
  restock: [
    { name: "芦笋", type: "蔬菜", quantity: 5 },
    { name: "香蕉", type: "水果", quantity: 0 },
    { name: "樱桃", type: "水果", quantity: 5 }
  ],
  ok: [
    { name: "山羊", type: "肉", quantity: 23 },
    { name: "鱼", type: "肉", quantity: 22 }
  ]
}
*/

规范

Specification
ECMAScript Language Specification
# sec-object.groupby

浏览器兼容性

BCD tables only load in the browser

参见