一、原生分组方法Object.groupBy()
好消息,所有现代浏览器都已经支持浏览器原生的静态方法Object.groupBy()
了,如下图所示,Safari浏览器支持最晚,今年4月份才开始支持。
这就意味着最晚明年,就算不使用Polyfill代码,也能在生产环境使用该方法了。
作用
Object.groupBy()
可以让可枚举对象,根据某个键进行自动分组。
例如:
const data = [{
id: 1,
name: '张三'
}, {
id: 3,
name: '李四'
}, {
id: 4,
name: '王二'
}, {
id: 2,
name: '张三'
}];
const result = Object.groupBy(data, ({ name}) => name);
console.log(result);
输入结果则是:
{张三: Array(2), 李四: Array(1), 王二: Array(1)}
张三: Array(2)
0: {id: 1, name: '张三'}
1: {id: 2, name: '张三'}
length: 2
[[Prototype]]: Array(0)
李四: Array(1)
0: {id: 3, name: '李四'}
length: 1
[[Prototype]]: Array(0)
王二: Array(1)
0: {id: 4, name: '王二'}
length: 1
[[Prototype]]: Array(0)
截图如下:
语法
Object.groupBy(items, callbackFn)
items : 将被分组的可迭代对象。
callbackFn(element, index) : 为可迭代对象中的每个元素执行的函数。其返回值会被作为键,用来指向分组后的数组项。使用以下参数调用该函数:
Polyfill代码
如果要兼容陈旧浏览器,可以试试使用这段JavaScript代码:
const hasGroup = typeof Object.groupBy === typeof undefined || typeof Array.groupToMap === typeof undefined || typeof Array.group === typeof undefined;
if (!hasGroup) {
const groupBy = (arr, callback) => {
return arr.reduce((acc = {}, ...args) => {
const key = callback(...args);
acc[key] ??= []
acc[key].push(args[0]);
return acc;
}, {});
};
if (typeof Object.groupBy === typeof undefined) {
Object.groupBy = groupBy;
}
if (typeof Array.groupToMap === typeof undefined) {
Array.groupToMap = groupBy;
}
if (typeof Array.group === typeof undefined) {
Array.group = groupBy;
}
}
二、实际案例
我在某项目开发中已经使用过此API了,给大家演示下使用场景。
已知有数组:
const okrAlignList = [{
objectId: 1,
empNum: 'YW001',
empName: '刘一'
}, {
objectId: 3,
empNum: 'YW002',
empName: '姚二三'
}, {
objectId: 4,
empNum: 'YW003',
empName: '张鑫旭'
}, {
objectId: 2,
empNum: 'YW001',
empName: '刘一'
}]
然后页面渲染的时候,如果是同一人,是需要合并展示的,如配图所示。
此时,我们就可以直接使用Object.groupBy()
方法进行渲染,而不需要自己额外写一个分组方法了,此时的Vue模板渲染使用下面的就可以了:
<data
v-for="(value, key) in Object.groupBy(okrAlignList, obj => obj.empNum)"
:key="key"
>
{{ value[0].empName }}<output v-if="value.length > 1">
({{ value.length}})
</output>
</data>
代码简洁多了。
三、还有Map.groupBy()方法
除了Object
对象有groupBy()
静态方法,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 },
];
const restock = { restock: true };
const sufficient = { restock: false };
const result = Map.groupBy(inventory, ({ quantity }) =>
quantity < 6 ? restock : sufficient,
);
console.log(result.get(restock));
// [{ name: "bananas", type: "fruit", quantity: 5 }]
Map.groupBy()
使用用在分组信息会随时间变化的场景下,因为即使对象被修改,它仍将继续作为返回Map的键。
其他时候,换成使用Object.groupBy()
实现也是可以的。
四、噢啦,结束了,就这些
好了,就这点内容,算是我众多文章里面比较水的一篇了吧。
我一般较少介绍纯JavaScript语言的API就是这个原因。
就是干巴巴的语法这些,都是其他地方都能找到的。
不像CSS这东西,可以有很多精彩的案例示意,会有众多衍生的表现。
总之,重要的是让大家知道浏览器新支持了个这么玩意。
日后在开发项目的时候,可以省掉些代码,提高点编码速度。
好,就说这些吧。
感谢阅读,欢迎分享。
(本篇完)