by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11357
本文可全文转载,独立域名个人网站无需授权,但需要保留原作者、出处以及文中链接,任何网站均可摘要聚合,商用请联系授权。
好消息,所有现代浏览器都已经支持浏览器原生的静态方法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)
如果要兼容陈旧浏览器,可以试试使用这段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>
代码简洁多了。
除了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这东西,可以有很多精彩的案例示意,会有众多衍生的表现。
总之,重要的是让大家知道浏览器新支持了个这么玩意。
日后在开发项目的时候,可以省掉些代码,提高点编码速度。
好,就说这些吧。
感谢阅读,欢迎。
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11357
(本篇完)