当前位置: 首页 > 科技观察

javascript最优雅的数据分组方法

时间:2023-03-12 04:32:49 科技观察

大家好,我是ConardLi,今天我们就来看一个数据分组的小技巧。分组数据是我们在开发中经常遇到的需求。有许多方法可以使用JavaScript对数据进行分组。然而,由于缺乏原生方法的支持,我们实现的数据分组功能通常冗长且难以理解。.不过,我想告诉你一个好消息。专用于数据分组的提案Array.prototype.groupBy已进入第3阶段!在看这个提议之前,让我们回顾一下我们以前在JavaScript中是如何分组的。前面的方法假设我们有以下一组数据:constitems=[{type:'clothes',value:'👔',},{type:'clothes',value:'👕',},{type:'衣服',value:'👗',},{type:'animal',value:'🐷',},{type:'animal',value:'🐸;',},{type:'animal',value:'🐒',},];我们希望按类型分组为以下格式:,},{type:'衣服',value:'👗',},],animal:[{type:'animal',value:'🐷',},{type:'animal',value:'🐸',},{type:'animal',value:'🐒',},],};我们可以采用如下的写法:for循环最直接易懂的写法就是代码很多。constgroupedBy={};for(constitemofitems){if(groupedBy[item.type]){groupedBy[item.type].push(item);}else{groupedBy[item.type]=[item];}}减少使用Array.protoype.reduce语法看起来很简单,但是读起来太难了。items.reduce((acc,item)=>({...acc,[item.type]:[...(acc[item.type]??[]),item],}),{},);我们稍微修改了一下,让它更容易理解,语法类似于上面的for循环:items.reduce((acc,item)=>{if(acc[item.type]){acc[item.type]。推送(项目);}else{acc[item.type]=[item];}returnacc;},{});过滤使用Array.prototype.filter,代码看起来容易阅读,但是性能较差,需要对数组进行多次过滤,如果type属性值很多,需要做更多的过滤操作。constgroupedBy={fruit:items.filter((item)=>item.type==='衣服'),vegetable:items.filter((item)=>item.type==='动物'),};其他如果不想用reduce,又想用函数式写法,可以这样写:Object.fromEntries(Array.from(newSet(items.map(({type})=>type))).map((type)=>[type,items.filter((item)=>item.type===type),]));是不是很郁闷🤯~Array.prototype.groupBy好现在,如果你使用Array.prototype.groupBy,你只需要下面这行代码:items.groupBy(({type})=>type);groupBy的回调中有三个参数:参数一:数组遍历到Object的当前值参数二:index索引参数三:原始数组constarray=[1,2,3,4,5];//groupBygroupsitemsbyarbitrarykey。//Inthiscase,we'regroupingbyeven/oddkeysarray.groupBy((num,index,array)=>{returnnum%2===0?'even':'odd';});此外,您还可以使用groupByToMap将数据分组到一个Map对象中。//groupByToMappreturnssitemsinaMap,andisusefulforgroupingusing//anobjectkey.constodd={odd:true};consteven={even:true};array.groupByToMap((num,index,array)=>{returnnum%2===0?even:odd;});//=>Map{{odd:true}:[1,3,5],{even:true}:[2,4]}