如何用ES6的filter/reduce方法按key分组对象数组?
按性别分组数组对象的解决方案
嘿,这个需求用ES6的filter和reduce完全可以搞定,而且能帮你写出超简洁的代码!我分两种方法给你演示,适配不同的使用场景:
方法一:使用filter(衔接你已有的思路)
你已经知道用filter分别筛选出男性和女性的数组,那要组合成目标对象其实超简单——直接用ES6的对象属性简写把两个数组包起来就行:
const data = [{ name: 'James', sex: 'male' }, { name: 'Mike', sex: 'male' }, { name: 'Janet', sex: 'female' }, { name: 'Mary', sex: 'female' }]; // 筛选出男性数组 const males = data.filter(item => item.sex === 'male'); // 筛选出女性数组 const females = data.filter(item => item.sex === 'female'); // 用ES6对象属性简写组合成目标对象,等价于 { males: males, females: females } const result = { males, females }; console.log(result);
这个方法逻辑特别直观,和你之前的思路完美衔接,唯一的小缺点是需要遍历原数组两次(一次筛选男性,一次筛选女性),不过对于小体量的数据来说完全够用。
方法二:使用reduce(更高效的一次遍历)
如果你想只遍历一次数组就搞定分组,那reduce绝对是你的不二之选!它能帮你在遍历的过程中一步步搭建出目标对象:
const data = [{ name: 'James', sex: 'male' }, { name: 'Mike', sex: 'male' }, { name: 'Janet', sex: 'female' }, { name: 'Mary', sex: 'female' }]; const result = data.reduce((acc, item) => { // 根据性别匹配对应的键名(male对应males,female对应females) const key = item.sex === 'male' ? 'males' : 'females'; // 当前对象推入对应的数组 acc[key].push(item); // 返回累计器,继续下一次遍历 return acc; }, { males: [], females: [] }); // 初始化累计器为包含两个空数组的对象 console.log(result);
这里我们提前给reduce设置了目标对象的初始结构,省去了判断键是否存在的步骤,代码变得更紧凑。这种方法只需要遍历原数组一次,对于大数据量来说性能会更好。
总结一下,两种方法都能达到你的需求:追求直观好理解就选filter的组合方式;想更高效就用reduce的一次遍历方案~
内容的提问来源于stack exchange,提问作者Myles
相关产品推荐
相关产品推荐

