reduce函数介绍(1)

相关知识点reduce函数:(reduce 是 JavaScript 数组方法中最强大、最灵活的一个——几乎所有数组操作都可以用 reduce 实现。它本质上是把一个数组"归纳"成一个值。)

 1 array.reduce((accumulator, currentValue, index, array) => {
 2   // 返回新的 accumulator
 3 }, initialValue)
 4 
 5 /* 
 6 accumulator(累加器)    上一次回调的返回值,或 initialValue
 7 currentValue(当前值)    当前正在处理的元素
 8 index(索引)    当前元素的索引(可选)
 9 array(原数组)    调用 reduce 的数组(可选)
10 initialValue(初始值)    第一次调用回调时的 accumulator
11 
12 */
13 
14 [1, 2, 3, 4].reduce((acc, cur) => acc + cur, 0)
15 
16    acc    cur     return
17    ─────────────────────
18     0   +  1   =   1     ← 第1次
19     1   +  2   =   3     ← 第2次
20     3   +  3   =   6     ← 第3次
21     6   +  4   =   10    ← 第4次
22 
23 最终结果: 10

所有数组方法都可以用 reduce 模拟

const arr = [1, 2, 3, 4, 5]

// ─── map ───
arr.map(x => x * 2)
// 等价于
arr.reduce((acc, cur) => [...acc, cur * 2], [])
// [2, 4, 6, 8, 10]

// ─── filter ───
arr.filter(x => x > 2)
// 等价于
arr.reduce((acc, cur) => cur > 2 ? [...acc, cur] : acc, [])
// [3, 4, 5]

// ─── find ───
arr.find(x => x > 3)
// 等价于
arr.reduce((acc, cur) => (acc !== undefined ? acc : (cur > 3 ? cur : undefined)), undefined)
// 4

// ─── some ───
arr.some(x => x > 4)
// 等价于
arr.reduce((acc, cur) => acc || cur > 4, false)
// true

// ─── every ───
arr.every(x => x > 0)
// 等价于
arr.reduce((acc, cur) => acc && cur > 0, true)
// true

// ─── flat ───
[[1, 2], [3, 4], [5]].flat()
// 等价于
[[1, 2], [3, 4], [5]].reduce((acc, cur) => [...acc, ...cur], [])
// [1, 2, 3, 4, 5]

// ─── forEach ───
arr.forEach(x => console.log(x))
// 等价于
arr.reduce((_, cur) => { console.log(cur) }, null)

 

三、前端经典实战场景

场景 1:求和 / 求积 / 统计

 1 // 求和
 2 const numbers = [1, 2, 3, 4, 5]
 3 const sum = numbers.reduce((acc, cur) => acc + cur, 0)
 4 console.log(sum)  // 15
 5 
 6 // 求积
 7 const product = numbers.reduce((acc, cur) => acc * cur, 1)
 8 console.log(product)  // 120
 9 
10 // 统计出现次数
11 const fruits = ['苹果', '香蕉', '苹果', '橘子', '香蕉', '苹果']
12 const count = fruits.reduce((acc, cur) => {
13   acc[cur] = (acc[cur] || 0) + 1
14   return acc
15 }, {})
16 console.log(count)  // { 苹果: 3, 香蕉: 2, 橘子: 1 }

 

场景 2:数组去重

 1 const arr = [1, 2, 2, 3, 4, 4, 5, 1, 3]
 2 
 3 // 方法1:基本去重
 4 const unique = arr.reduce((acc, cur) => {
 5   if (!acc.includes(cur)) {
 6     acc.push(cur)
 7   }
 8   return acc
 9 }, [])
10 console.log(unique)  // [1, 2, 3, 4, 5]
11 
12 // 方法2:Set 去重(性能更好,但 reduce 可以加更多逻辑)
13 const unique2 = arr.reduce((acc, cur) => {
14   return acc.add(cur)
15 }, new Set())
16 console.log([...unique2])  // [1, 2, 3, 4, 5]
17 
18 // 方法3:对象去重(保留最后一次出现的重复项)
19 const items = [
20   { id: 1, name: 'A' },
21   { id: 2, name: 'B' },
22   { id: 1, name: 'C' },  // 重复 id
23   { id: 3, name: 'D' }
24 ]
25 const uniqueById = items.reduce((acc, cur) => {
26   acc[cur.id] = cur  // 后出现的覆盖先出现的
27   return acc
28 }, {})
29 console.log(Object.values(uniqueById))
30 // [{ id: 1, name: 'C' }, { id: 2, name: 'B' }, { id: 3, name: 'D' }]

 

场景 3:数组转对象(分组)

 1 // 按属性分组
 2 const users = [
 3   { name: '张三', role: 'admin' },
 4   { name: '李四', role: 'user' },
 5   { name: '王五', role: 'admin' },
 6   { name: '赵六', role: 'user' },
 7   { name: '钱七', role: 'guest' }
 8 ]
 9 
10 const groupByRole = users.reduce((acc, user) => {
11   (acc[user.role] = acc[user.role] || []).push(user)
12   return acc
13 }, {})
14 
15 console.log(groupByRole)
16 // {
17 //   admin: [{ name: '张三', role: 'admin' }, { name: '王五', role: 'admin' }],
18 //   user: [{ name: '李四', role: 'user' }, { name: '赵六', role: 'user' }],
19 //   guest: [{ name: '钱七', role: 'guest' }]
20 // }
21 
22 // 通用分组函数
23 function groupBy(arr, keyFn) {
24   return arr.reduce((acc, item) => {
25     const key = typeof keyFn === 'function' ? keyFn(item) : item[keyFn]
26     (acc[key] = acc[key] || []).push(item)
27     return acc
28   }, {})
29 }
30 
31 // 使用
32 console.log(groupBy(users, 'role'))
33 console.log(groupBy(users, (u) => u.name.length > 1 ? '长名' : '短名'))

 

场景 4:扁平化嵌套数组

 1 // 扁平化一层
 2 const nested = [[1, 2], [3, 4], [5, 6]]
 3 const flat = nested.reduce((acc, cur) => [...acc, ...cur], [])
 4 // [1, 2, 3, 4, 5, 6]
 5 
 6 // 递归扁平化任意深度
 7 function flattenDeep(arr) {
 8   return arr.reduce((acc, cur) => {
 9     return Array.isArray(cur)
10       ? [...acc, ...flattenDeep(cur)]
11       : [...acc, cur]
12   }, [])
13 }
14 
15 console.log(flattenDeep([1, [2, [3, [4, 5]]]]))
16 // [1, 2, 3, 4, 5]
17 
18 // 扁平化 + 去重 + 排序
19 const messy = [[3, 1], [2, 3], [1, [4, 2]]]
20 const result = messy
21   .reduce((acc, cur) => [...acc, ...(Array.isArray(cur) ? flattenDeep(cur) : [cur])], [])
22   .reduce((acc, cur) => acc.includes(cur) ? acc : [...acc, cur], [])
23   .sort((a, b) => a - b)
24 console.log(result)  // [1, 2, 3, 4]
posted @ 2026-08-12 10:50  小新的蜡笔  阅读(3)  评论(0)    收藏  举报