news 2026/3/21 11:15:10

高阶函数之-数据分组的思考

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
高阶函数之-数据分组的思考

看一个例子,刚开始,你可能会这样写

constpeople=[{name:'ALice',age:30,sex:'female'},{name:'BOb',age:25,sex:'male'},{name:'Chartlie',age:30,sex:'male'},{name:'Diana',age:25,sex:'female'},{name:'Eva',age:25,sex:'female'},{name:'Frank',age:25,sex:'male'},{name:'Grace',age:20,sex:'female'},];// 按年龄分组constresult={};for(constitemofpeople){constkey=item.age;if(!result[key]){result[key]=[];}result[key].push(item);}

但有一天可能按照性别分组,你不得不重新写一下代码,改成下面这样

constpeople=[{name:'ALice',age:30,sex:'female'},{name:'BOb',age:25,sex:'male'},{name:'Chartlie',age:30,sex:'male'},{name:'Diana',age:25,sex:'female'},{name:'Eva',age:25,sex:'female'},{name:'Frank',age:25,sex:'male'},{name:'Grace',age:20,sex:'female'},];// 按年龄分组// const result = {};// for(const item of people){// const key = item.age;// if(!result[key]){// result[key]=[];// }// result[key].push(item);// }// 按性别分组constresult={};for(constitemofpeople){constkey=item.sex;if(!result[key]){result[key]=[];}result[key].push(item);}

此时,我们应该想到应该写一个通用的分组函数来完成分组操作

//分组函数functiongroupBy(arr,propName){constresult={};for(constitemofarr){constkey=item[propName];if(!result[key]){result[key]=[];}result[key].push(item);}returnresult}constresult1=groupBy(people,'age')constresult2=groupBy(people,'sex')

此时到这还没结束,可能有一天我们那个数组的某个元素又是一个对象的话,比如address:{province:"河南’,city:‘开封’},我们可能想按照省份分组又该怎么做呢,再比如如果是按照年龄加上性别来分组,还有可能按照分组的数据是一个数字,让他按照奇偶数来分组又应该如何做呢,这个函数又用不了了,那么如何能让该函数更加的通用适应所有的分组操作呢,其实关键就在于那个键值key,他不应该仅仅是一个字符串,他的获取应该是一个过程,获取属性名来得到键只是这种过程中的一种,那么考虑到这一点,我们发现,他应该是一个函数才对,

//分组函数functiongroupBy(arr,generateKey){constresult={};for(constitemofarr){constkey=generateKey(item);if(!result[key]){result[key]=[];}result[key].push(item);}returnresult}// 按年龄constresult1=groupBy(people,(item)=>item.age)// 按性别constresult2=groupBy(people,(item)=>item.sex)// 按年龄-性别constresult3=groupBy(people,(item)=>`${item.age}-${item.sex}`)// 如果数组是存数字constarr=[34,6,321,3,5,7];constresult4=groupBy(arr,(item)=>item%2===0?'偶':'奇')

那么这个函数在功能上是没有什么问题了,但是在使用上还不那么舒服,我们希望他支持两种方式来传递,第一种按照属性名来分组,第二种按照函数来,那么这个参数就出现了两种情况,那么就需要用到参数归一化了

//分组函数functiongroupBy(arr,generateKey){if(typeofgenerateKey==='string'){constpropName=generateKey;generateKey=(item)=>item[propName]}constresult={};for(constitemofarr){constkey=generateKey(item);if(!result[key]){result[key]=[];}result[key].push(item);}returnresult}// 按年龄constresult1=groupBy(people,'age')// 按性别constresult2=groupBy(people,'sex')// 按年龄-性别constresult3=groupBy(people,(item)=>`${item.age}-${item.sex}`)// 如果数组是存数字constarr=[34,6,321,3,5,7];constresult4=groupBy(arr,(item)=>item%2===0?'偶':'奇')

非原创,来自渡一袁老师,简单记录,每日分享

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!