JavaScript:使用 Reduce() 构建对象并消除循环

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 函数内添加其他过程时需要注意这一点。