如何优化实现数组分组的reduce函数 去除if语句与显式return
错误原因
- 条件判断逻辑错误:
[jaulaId] ?实际是判断字面量新数组[jaulaId]的布尔值,非空数组恒为真,永远走第一个分支,完全没有达到判断累加器中是否存在对应jaulaId属性的目的。 - 错误使用
push返回值:数组push方法的返回值是操作后数组的长度,不是修改后的数组本身,这会导致最终每个键对应的值都是数字而非comunaCode组成的数组。 - 取值逻辑错误:第一个分支中你写的
[jaulaId].push(comunaCode)是对新建的[jaulaId]数组操作,完全没有用到累加器中已存的同jaulaId下的comunaCode列表,会丢失历史数据。
正确优化实现
写法1(纯函数式无修改,符合你展开对象的写法习惯)
const joinCages2 = arr => arr.reduce((acc, { jaulaId, comunaCode }) => ({ ...acc, [jaulaId]: [...(acc[jaulaId] || []), comunaCode] }), {})
代码说明:
用acc[jaulaId] || []代替if判断:如果累加器中已存在当前jaulaId对应的数组就直接用,不存在就兜底为空数组,完全去掉了if分支;用数组展开语法代替push操作,避免了push返回值为长度的问题,同时每次拼接新的comunaCode到对应数组末尾;reduce回调直接返回对象字面量,实现隐式return,没有显式return语句。
写法2(高性能,和原始写法性能一致)
如果你的原始数组数据量非常大,每次展开整个累加器对象会有性能损耗,可以用下面这种兼顾性能、无if、隐式return的写法:
const joinCages2 = arr => arr.reduce((acc, { jaulaId, comunaCode }) => ( (acc[jaulaId] ??= []).push(comunaCode), acc ), {})
说明:这里用逗号运算符,先执行赋值+push操作,最后返回累加器对象,不需要每次展开整个对象,性能和原始写法一致,同时也满足无if、隐式return的要求。用逻辑空赋值
??=判断如果不存在对应属性就先赋值为空数组,完全替代原来的if判断。
内容的提问来源于stack exchange,提问作者Programmer89
相关产品推荐
相关产品推荐

