You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript数组通过reduce转换为统计对象的分步原理解析

数组元素统计:reduce方法的运行机制与分步流程

先看你给出的代码:

const arr = [1, 3, 1, 2, 5, 2, 3, 4, 1, 2, 3, 4, 3]
const resultado = arr.reduce((prev, cur) => ((prev[cur] = prev[cur] + 1 || 1), prev), {})
// resultado = { 1: 3, 2: 3, 3: 4, 4: 2, 5: 1 }

一、核心逻辑:用reduce实现元素计数

Array.reduce()是JS中用来遍历数组并累计结果的方法,这里的作用是把数组转换成统计元素出现次数的对象,核心参数有两个:

  1. 回调函数:每次遍历数组元素时执行,接收两个关键参数:
    • prev:累计器,存储每次遍历后的中间结果(这里是统计对象)
    • cur:当前正在遍历的数组元素
  2. 初始值{}:第一次遍历前,prev的初始值是空对象。

拆解回调函数的写法

回调里的((prev[cur] = prev[cur] + 1 || 1), prev)用了两个JS语法技巧:

  • 逗号运算符:逗号分隔的多个表达式会依次执行,最终返回最后一个表达式的值。这里每次执行完计数逻辑后,返回prev,保证累计器始终是同一个统计对象。
  • 逻辑或||:处理元素第一次出现的情况:
    • 如果prev[cur]已经存在(之前统计过),就执行prev[cur] + 1,更新计数
    • 如果prev[cur]不存在(第一次遇到),prev[cur]是undefined,undefined + 1得到NaN,NaN是假值,所以会取||后面的1,完成第一次计数赋值。

二、分步遍历流程

跟着数组的每一个元素,一步步看prev的变化:

初始状态:prev = {}

  1. 遍历第一个元素1:prev[1]不存在,执行prev[1] = 1 → prev = {1: 1}
  2. 遍历第二个元素3:prev[3]不存在,执行prev[3] = 1 → prev = {1: 1, 3: 1}
  3. 遍历第三个元素1:prev[1]是1,执行1 + 1 = 2 → prev = {1: 2, 3: 1}
  4. 遍历第四个元素2:prev[2]不存在,执行prev[2] = 1 → prev = {1: 2, 3: 1, 2: 1}
  5. 遍历第五个元素5:prev[5]不存在,执行prev[5] = 1 → prev = {1: 2, 3: 1, 2: 1, 5: 1}
  6. 遍历第六个元素2:prev[2]是1,执行1 + 1 = 2 → prev = {1: 2, 3: 1, 2: 2, 5: 1}
  7. 遍历第七个元素3:prev[3]是1,执行1 + 1 = 2 → prev = {1: 2, 3: 2, 2: 2, 5: 1}
  8. 遍历第八个元素4:prev[4]不存在,执行prev[4] = 1 → prev = {1: 2, 3: 2, 2: 2, 5: 1, 4: 1}
  9. 遍历第九个元素1:prev[1]是2,执行2 + 1 = 3 → prev = {1: 3, 3: 2, 2: 2, 5: 1, 4: 1}
  10. 遍历第十个元素2:prev[2]是2,执行2 + 1 = 3 → prev = {1: 3, 3: 2, 2: 3, 5: 1, 4: 1}
  11. 遍历第十一个元素3:prev[3]是2,执行2 + 1 = 3 → prev = {1: 3, 3: 3, 2: 3, 5: 1, 4: 1}
  12. 遍历第十二个元素4:prev[4]是1,执行1 + 1 = 2 → prev = {1: 3, 3: 3, 2: 3, 5: 1, 4: 2}
  13. 遍历第十三个元素3:prev[3]是3,执行3 + 1 = 4 → prev = {1: 3, 2: 3, 3: 4, 4: 2, 5: 1}

遍历结束后,prev就是最终的统计结果,赋值给resultado。

内容的提问来源于stack exchange,提问作者Brian Cabrera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 19:06:25