JavaScript 的 reduce
方法将一个数组缩减为一个单一值,但这到底是什么意思,为什么它有用?JavaScript 提供了多种遍历数组的方法,那么为什么要使用 reduce
呢?
reduce()
方法类似于内置的数组 map
方法,但具有更多的内置功能。
让我们从基础开始。reduce
的必需参数是累加器、当前值和初始值。函数的基础结构如下所示。
累加器
(在 MDN 文档中称为“前一个值”)是所有之前的值和初始值(如果需要初始值)所设定的值。当前值
是在reduce
函数中稍后执行回调或操作的对象。初始值
是累加器的起始值。如果数组被缩减为一个数字,那么初始值将是一个整数。如果创建的是一个对象,那么初始值将是一个对象。如果创建的是一个数组,那么初始值将是一个数组。
还有其他选项,例如当前索引或数组,这些可以指定但不是必需的。
为了更容易理解,请参阅以下这个简单的循环函数作为示例。sum
变量执行的是累加器的功能。array[I]
是循环中每次迭代的当前值。
上面的循环表示为 reduce
方法如下所示:reduce
也适用于处理对象数组时。需要注意的一点是,当代码行数多于一行时,返回语句是绝对必要的。下面的示例展示了在 reduce
回调中的累加器 console.log
以及第一个多行 reduce
示例。
使用 reduce
构建对象
与前面的例子类似,初始值将决定 reduce
函数其余部分的运作节奏。所以当初始值为 0 时,所有其他值都将加到这个 0 上。当初始值为空对象时,剩余的值将添加到该空对象中。基础的 reduce
函数将如下所示:
如果我们想将示例中的水果对象数组转换为一个单一的对象,它的形式如下:
这里有一种方法可以使其更简短。这是该方法的语法糖版本,它看起来像这样。
上面的示例是对前一个累加器的副本进行操作,并将当前值的键/值对添加到其中。
但如果要处理的是一个字符串数组而不是对象数组呢?没问题!结构是类似的。reduce
可以用来创建一个包含元素及其索引的对象。
还可以将其他回调函数传递给 reduce
函数。这里有一个非常基本的例子:
最后一个构建对象的例子是计数对象。在这个例子中,正在构建的对象将记录每种水果在数组中出现的次数。
计数对象的一种版本如下:
有一种方法可以使这个解决方案稍微更优雅。类似于上面的语法糖,扩展运算符将复制前一个累加器对象并添加新的键/值对。括号中的值表示以下含义:要么将键的值设置为该键的当前值或 0,然后加 1。这种方法在 reduce
函数之外也适用。
使用 reduce
构建数组
reduce
可用于构建数组。通过将初始值设置为空数组,reduce
函数将把值累积到数组中。如下所示:
构建数组与构建对象类似。reduce
可以构建数组和数组的数组。下面是一个 reduce
方法构建数组的例子:
这是 reduce
用于构建数组的数组的例子:
还可以将回调函数传递给数组:
结论
reduce
是 JavaScript 中多种遍历数组方式中的另一个有用工具。reduce
在链式调用高阶函数和抽象掉循环过程时非常有用。由于它会遍历数组中的所有元素,因此时间复杂度为 O(n),在 reduce
函数内添加其他过程时需要注意这一点。