请求详解JavaScript中基于reduce实现的数组分组代码
理解JavaScript的reduce分组逻辑:逐迭代拆解讲解
我正在学习JavaScript的reduce方法,有基础理解,但遇到复杂代码就无从下手。能理解求和这类简单的reduce示例,但下面这段实现数组分组的reduce代码让我困惑,尤其是acc[key] ?? []的作用。请帮我逐迭代讲解这段代码的执行过程。
先回顾简单reduce求和示例
const array1 = [1, 2, 3, 4]; // 0 + 1 + 2 + 3 + 4 const initialValue = 0; const sumWithInitial = array1.reduce( (accumulator, currentValue) => accumulator + currentValue, initialValue ); console.log(sumWithInitial); // Expected output: 10
需要理解的分组reduce代码
const people = [ { name: "Alice", age: 21 }, { name: "Max", age: 20 }, { name: "Jane", age: 20 }, ]; function groupBy(objectArray, property) { return objectArray.reduce((acc, obj) => { const key = obj[property]; const curGroup = acc[key] ?? []; return { ...acc, [key]: [...curGroup, obj] }; }, {}); } const groupedPeople = groupBy(people, "age"); console.log(groupedPeople); // { // 20: [ // { name: 'Max', age: 20 }, // { name: 'Jane', age: 20 } // ], // 21: [{ name: 'Alice', age: 21 }] // }
逐迭代拆解分组代码执行过程
首先明确reduce核心参数:
acc:累加器,每次迭代后返回的结果,初始值是传入的{}(空对象)obj:当前迭代到的数组元素- 本次按
age属性分组,所以每次迭代的key是当前对象的age值
第一次迭代:处理{ name: "Alice", age: 21 }
key = obj["age"]→ 21curGroup = acc[21] ?? []:此时acc是空对象,acc[21]为undefined,空值合并运算符??会取右侧默认值[],所以curGroup = []- 返回新对象:
{ ...acc, [21]: [...curGroup, obj] }→ 展开空对象后添加21: [ { name: "Alice", age: 21 } ],此时acc变为{ 21: [ { name: "Alice", age: 21 } ] }
第二次迭代:处理{ name: "Max", age: 20 }
key = obj["age"]→ 20curGroup = acc[20] ?? []:当前acc中没有20这个键,acc[20]为undefined,所以curGroup = []- 返回新对象:
{ ...acc, [20]: [...curGroup, obj] }→ 展开之前的acc(包含21的数组),添加20: [ { name: "Max", age: 20 } ],此时acc变为{ 21: [ { name: "Alice", age: 21 } ], 20: [ { name: "Max", age: 20 } ] }
第三次迭代:处理{ name: "Jane", age: 20 }
key = obj["age"]→ 20curGroup = acc[20] ?? []:当前acc中已有20这个键,对应值是[ { name: "Max", age: 20 } ],所以curGroup直接取这个数组,不会用默认值[]- 返回新对象:
{ ...acc, [20]: [...curGroup, obj] }→ 展开之前的acc,把20对应的数组展开后加入当前对象,变成[ { name: "Max", age: 20 }, { name: "Jane", age: 20 } ],此时acc就是最终的分组结果
重点解释acc[key] ?? []的作用
??是空值合并运算符,规则是:如果左侧值为null或undefined,返回右侧默认值;否则返回左侧值。
在分组场景中:
- 第一次遇到某个
key时,acc里还没有这个键,acc[key]为undefined,此时需要初始化空数组来存放同组元素 - 如果已经存在该
key,则直接复用已有的数组,避免覆盖之前的元素
如果不用?? [],第一次遇到新key时acc[key]是undefined,执行[...undefined, obj]会报错,所以这个表达式是为了安全初始化分组数组。
内容的提问来源于stack exchange,提问作者Tal
相关产品推荐
相关产品推荐

