我在另一篇文章中讲了Object.groupBy()数组分组聚合,Map.groupBy()和它很相似,只不过前一个返回的是POJO普通对象,而后一个返回的是Map类型对象。
新特性解决的问题
我们在处理数据库返回的数据时,时常要做各种分组聚合,举例如下:
const inventory = [
{ name: 'asparagus', type: 'vegetables', quantity: 9 },
{ name: 'bananas', type: 'fruit', quantity: 5 },
{ name: 'goat', type: 'meat', quantity: 23 },
{ name: 'cherries', type: 'fruit', quantity: 12 },
{ name: 'fish', type: 'meat', quantity: 22 },
];
假如现在数据库中存储了上述的各种不同的食物名称、分类和数量。
现在UI界面要求把需要补充库存的和不需要补充库存的分开显示。
我们可能需要这样一个数据结构:
{
{ restock: true }: [
{ name: 'bananas', type: 'fruit', quantity: 5 }
],
{ restock: false }: [
{ name: 'asparagus', type: 'vegetables', quantity: 9 },
{ name: 'goat', type: 'meat', quantity: 23 },
{ name: 'cherries', type: 'fruit', quantity: 12 },
{ name: 'fish', type: 'meat', quantity: 22 }
]
}
restock这个单词是需要重新进货的意思。
这里比较特殊的是对象的键名也是对象,很显然我们普通的JavaScript对象无法满足这种结构。这时就需要Map出场了,Map最大的特点就是键名可以是对象,而普通对象的键名只能是字符串或者Symbol。
下面我们来看看Map.groupBy是怎么解决问题的:
const restock = { restock: true, };
const sufficient = { restock: false };
const result = Map.groupBy(inventory, ({ quantity }) =>
quantity < 6 ? restock : sufficient,
);
// [{ name: "bananas", type: "fruit", quantity: 5 }]
console.log(result.get(restock));
// 打印结果看下图
console.log(result);
例子中可以看到restock和sufficient对象在Map.groupBy的回调函数中被返回,成为了result的键名,inventory数组中quantity小于6的和大于6的都汇聚成了数组分别成为了result的键值。
这就是新特性:Map.groupBy。
Map.groupBy
从上面的例子可以看出,Map.groupBy可以对目标数据集进行分组聚合。
下面咱们来看一下它的具体用法。
语法
Map.groupBy(items, callbackFn)
参数
items:
第一个参数items代表需要处理的可迭代对象,例如:数组。
callbackFn:
第二个参数callbackFn代表callback函数。
callbackFn函数的参数:
1. element:数组中的元素。
2. index:element的数组索引。
callbackFn的返回值规则:
callbackFn必须有返回值,每个返回值都会作为最终返回的Map对象的键名。如果多条数据的键名相同,则其值以数组的形式叠加起来。
返回值可以是对象也可以是基本类型(null也是可以的),其规则和Map类型的键名规则一致。这一点相当灵活。
如果没有返回值,那undefined会被作为返回值。
返回值
返回值是一个Map对象,对象的键名是callbackFn函数的返回值,键值是每个callbackFn函数的返回值所对应的数组项组成的数组。
所以说Map.groupBy做的事就是对目标数组进行分组。
语言解释确实比较困难且难懂,大家最好结合上面的例子,就什么都明白了。
浏览器兼容性
目前该特性已经到了 Stage 4 阶段,欲了解 Stage 4 的含义可以看这篇文章 各大主流浏览器也是刚刚开始支持。
其实Map.groupBy和Object.groupBy同属一个ECMAScript提案,它们都是为了更好的处理数组。
Polyfill
corejs已经有对应的Polyfill。
结束语
ES2024系列专辑将持续更新将在2024年发布的新特性。敬请关注!
注:以上例子部分参考了MDN。