reduce, reduceRight
撰写时间:2024-03-05
最新修订:2025-02-26
reduce, reduceRight
将每轮回调函数返回的运算结果送至下一轮参与运算。
- reduce方法从左到右遍历元素。
- reduceRight方法从右到左遍历元素。
原型
- functioncallbackFn
- *initialValue
- functioncallbackFn
- *initialValue
参数
- callbackFn
-
回调函数。该回调函数接受4个参数。其原型如下:
*callbackFn- *accumulator
- *currentValue
- numbercurrentIndex
- *[]array
- accumulator
- 上一轮累积下来的运算结果。
- currentValue
- 当前遍历到的数组元素值。
- currentIndex
- 当前遍历到的数组元素的索引值。
- array
- 调用reduce方法的数组实例。
每轮回调函数的返回值,将作为下一轮回调函数的accumulator的值传给下一轮回调函数。
- initialValue
- 指定一个初始值作为accumulator的值,以在第一轮的遍历中与数组第0个元素共同参与运算。
返回值
返回每次遍历都进行累积的运算结果。
说明
reduce方法将每轮回调函数返回的运算结果送至下一轮参与运算。最终返回一个累积的运算结果。
reduceRight方法功能与reduce一样,但遍历次序是从右到左。
例子
指定初始值
与forEach等方法的回调函数不同的是,reduce方法的回调函数还需要返回一个数值。因此,要理解reduce方法,应观察分析其回调函数的特点。我们先以累积求和为例:
回调函数每一轮都需有一个返回值,每轮回调函数的返回值,将作为下一轮回调函数的accumulator的值传给下一轮回调函数。因此,在每一轮的回调函数中,需要明确当前所遍历到的元素与accumulator的逻辑关系。最常见的应用是相加,以累积求和。
在这种场合下,accumulator为之前已经遍历过的所有元素之和,而在每轮中,又需要将本轮遍历到的元素与accumulator相加并予以返回。
而较为费脑的是,在第一轮遍历时,参数accumulator值尚未求出,如何确定其值?
这就是reduce方法的最后一个参数initialValue存在的意义所在。当我们指定了该参数的值,该值将作为accumulator的值,以在第一轮的遍历中与数组第0个元素共同参与运算。当本轮返回这个运算结果后,参数accumulator将被赋值于此值,并传入到第二轮的遍历中。这样,在以后每轮遍历中,只需将当前遍历到的currentValue与其相加并返回即可。
下面的代码根据上面的原理,求出数组所有元素之和。
第一轮遍历,初始值0与第0个数组元素1相加并返回给accumulator。第二轮遍历,accumulator再与第1个数组元素2相加再返回并赋值给accumulator。依此类推。这样便实现了数组各元素累积相加的效果。
不指定初始值
如果不指定初始值,则在第一轮遍历中,将数组第0个元素作为参数accumulator的值,将数组第1个元素作为currentValue的值,相对应的,currentIndex的值就为1。后面的遍历就依序进行。
因此,本例的结果仍为15,只不过本例少遍历了一次而已。
求数组最大值
将初始值设置为-Infinity,即负无穷小,可确保在第1轮的比较中返回数组第0个元素的值。
生成斐波那契数列
斐波那契数列的特点是,最前面的两项的值均为1,而从第3项开始,每一项都等于前两项之和。因此,其数列如:
下面使用reduce方法求出斐波那契数列:
这是一个反例。reduce方法的精华在于应用到有固定的多个元素的数组上面。而本例中,为避免重复计算,每次都移出栈底并将结果保存中arr中因而成为只有固定2个元素的数组,此时再调用reduce就有大材小用之嫌。因此,这里不是应用该方法的好场合。
此例可看出,reduce方法适用于数组成员数量已固定的情况。而求斐波那契数列值时,需要根据函数参数来确定参与运算的次数,数组成员数量是不固定的。这种情况下,使用递归函数就很便利。
在递归时,当参数n的值等于2时,递归中止,此时n等于1时的代码不被执行。但还应考虑到用户只需要数组元素数量为1时的情况,此时该段代码就起作用了。
斐波那契数列虽然不是几何增长,但此数增长速度还是非常快的,被称为可揭秘宇宙规律的生长数列或黄金分割数列。其所生成的图像参见绘制黄金矩形。