这篇文章发布于 2024年09月19日,星期四,23:32,归类于 JS API。 阅读 3740 次, 今日 4 次 3 条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11357
本文可全文转载,独立域名个人网站无需授权,但需要保留原作者、出处以及文中链接,任何网站均可摘要聚合,商用请联系授权。
一、原生分组方法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这东西,可以有很多精彩的案例示意,会有众多衍生的表现。
总之,重要的是让大家知道浏览器新支持了个这么玩意。
日后在开发项目的时候,可以省掉些代码,提高点编码速度。
好,就说这些吧。
感谢阅读,欢迎。
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11357
(本篇完)
- JS WeakMap应该什么时候使用 (0.600)
- Object.is/===、数组at/直接索引、substring/slice的区别 (0.400)
- JS数组的copyWithin()语法我看了好几遍才懂 (0.267)
- ES5中新增的Array方法详细说明 (0.200)
- HTML <area><map>标签及在实际开发中的应用 (0.200)
- 简单了解ES6/ES2015 Symbol() 方法 (0.133)
- 聊聊JS DOM变化的监听检测与应用 (0.133)
- Proxy是代理,Reflect是干嘛用的? (0.133)
- 深入 JS new Function 语法 (0.133)
前端已经死了,旭哥还在苦苦专研前端前沿技术,令人敬佩,可是实在没法做出什么惊心动魄的东西来
念头通达,阁下肯定是正派修士吧
旭哥,实际案例中,v-for 那里的{{ value[0].empName }}应该可以直接取key吧,?