一、语法
1.1、基础结构
reduce(callbackFn, initialValue)
1.2、callbackFn
把callbackFn展开就是这样的,它其中又包含了4个参数:
function (previousValue, currentValue, currentIndex, array) { }
当然callbackFn可以写成箭头函数
(previousValue, currentValue, currentIndex, array) => { }
1.3、initialValue
它的含义是:初始值,也就是说它可以作为一个初始值供遍历数组时累加或作别的处理,它是一个可选参数,可以传也可以不传。在下面介绍个参数含义的时候,会详细来说传与不传造成的结果。
1.4、各参数的意义
- previousValue:累加值或者叫做计算值、相加值,也就是上一次调用callbackFn的返回值;在第一次调用的时候,如果开发者声明了initialValue,其值就是initialValue,否则就是数组索引为0的元素。
- currentValue:数组当前正在处理的元素,在第一次调用的时候,如果开发者声明了initialValue,其值就是数组索引为0的元素,否则就是数组索引为1的元素。
- currentIndex:数组正在处理元素的索引,如果开发者声明了initialValue,则起始索引为0,否则为1。(我们可以对比发现currentValue和currentIndex取的是同一个位置的元素和索引,从哪个位置开始则取决于initialValue有没有声明)。
- array:调用了reduce用于遍历的数组。
二、例子
2.1、reduce处理运算,不设置initialValue
这个例子展示了reduce比较基础的计算能力用法,如果你迷糊了,先搞清楚我们这里箭头函数之后并没有声明initialValue初始值,也就是说previousValue(以下用prev代指)是默认选取了数组第一个元素也就是1,currentValue(以下用curr代指)和currentIndex(以下用index代指)都是从数组第二个元素开始的,那么也就是初始值是元素2,和元素2的下标1。每次调用都进行了prev+curr的计算操作,那么prev这个累计值也会每次更新为上次一计算的结果。
const arr = [1, 2, 3, 4, 5, 6]
const result = arr.reduce((prev, curr, index, array) => {
console.log(prev, curr, index)
return prev + curr
})
console.log(result)
/*
1 2 1
3 3 2
6 4 3
10 5 4
15 6 5
21
*/
2.2、reduce处理运算,设置initialValue
明白了上面的例子,现在我们加上initialValue初始值,我们给定它为10。那么注意了,这时prev、curr、index都和上面的例子不同了,prev初始值就是initialValue的10,curr和index则变成了数组第一个元素的值和下标。
const arr = [1, 2, 3, 4, 5, 6]
const result = arr.reduce((prev, curr, index, array) => {
console.log(prev, curr, index)
return prev + curr
}, 10)
console.log(result)
/*
10 1 0
11 2 1
13 3 2
16 4 3
20 5 4
25 6 5
31
*/
2.3、reduce处理接口中数据,按照key值分组
下面就是进阶的例子了,在开发过程中,有些个别情况后端给定的数据不一定满足我们遍历组件的需求,我们可以在请求responses之后用reduce来格式化它们,以达到我们需求的格式。
const res = [
{ name: 'Stefan', age: 24, job: 'Web' },
{ name: 'Edward', age: 28, job: 'Web' },
{ name: 'Peter', age: 25, job: 'Java' },
{ name: 'Jackson', age: 26, job: 'Python' }
]
const filterRes = res.reduce((prev, curr) => {
if (prev[curr]) {
prev[curr.job].push(curr)
} else {
prev[curr.job] = [curr]
}
return prev
}, {})
console.log(JSON.stringify(filterRes))
/*
{
'web': [{ name: 'Stefan', age: 24, job: 'Web' }, { name: 'Edward', age: 28, job: 'Web' }],
'Java': [{ name: 'Peter', age: 25, job: 'Java' }],
'Python': [{ name: 'Jackson', age: 26, job: 'Python' }]
}
*/