JavaScript 中的 reduce 方法为您提供了一种简单的方法来获取值数组并将它们组合成一个值,或者根据多个类别对数组求和。
哇,一句话说得太多了,让我们一步一步来吧!
当然,你可以使用 for 循环遍历数组并对每个值执行特定操作。但是,如果你不使用 filter()、map() 和 reduce() 等方法,那么你的代码将变得更加难以阅读。其他开发人员需要彻底阅读每个循环才能理解其目的, 而且容易出现更多的 bug,因为你需要创建更多的变量来跟踪单个值。
Filter 方法接受初始数组中的所有元素,并且只允许某些元素进入最终数组
Map 方法在初始数组中的每个元素上运行一个函数,然后将其存储在最终数组中。
而 reduce 方法将初始数组中的元素组合成最终值或值数组。
我意识到这有点像节食。从非常简单的方法,如计算卡路里,到更复杂的饮食,如 Atkins 减肥法或称体重计 (WeightWatchers),目标是将你一天中可能吃的所有食物提炼成一个(或多个) 值,看看你是否在减肥的轨道上。
用 For 循环模拟 Reduce
下面是使用 for 循环快速显示 reduce()功能的方法。假设你有一个包含你一天中吃过的 5 种不同食物的卡路里计数的数组,你想知道你总共消耗了多少卡路里, 代码如下:
这很简单,你创建一个变量来保存最终数量,然后在运行数组时添加它。但是,你仍然需要引入一个新变量,并且循环没有提供关于循环目的的线索。
一个简单的 Reduce 示例
让我们学习如何使用 reduce()方法实现相同的目标。
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。对空数组是不会执行回调函数的。
所以 reduce 有一些内存的概念。在遍历数组中的每一项时,sum 参数将跟踪值。在前面的例子中,我们必须在循环范围之外声明一个新变量来“记住”这些值。
这与 for()之间的可读性似乎没有太大区别。但是,当需要遍历数百行代码时,reduce 会让你快速了解代码块的用途。
例 2 – 使用对象
到目前为止,我们只举例一维数组。但是,如果您可以遍历一个都是数字的数组,那么你也可以遍历一个都是对象的数组。让我们给每个元素加一个名字,这样我们就能知道我们一天到底吃了什么。
你早餐吃了一份牛排,一些水果,然后午餐吃了一些沙拉和薯条,最后晚餐吃了冰淇淋,真是糟糕的一天!
希望你们能看到整个数组的流动。当我们研究每一种元素时,总热量的总和(sum)就代表了一天所消耗的总热量,主要是把这些数值放进一个大桶里——一天的卡路里量。
例 3 – 使用多个类别
所以如果这都是关于卡路里的,为什么会有这么多不同的饮食呢? 我不打算深究营养科学,但这里有一个概括性的总结——对于“最佳”减肥方法有很多分歧。有些人鼓励你只计算卡路里,而另一些人则关注蛋白质、碳水化合物、脂肪和其他任何因素。
让我们设想一下,你希望更改代码,以便能够基于任何常见的节食系统评估您的饮食。你需要追踪每种食物的碳水化合物和脂肪,然后你需要在最后统计一下,这样你就能算出你在每个类别中消耗了多少克,以下我们的食品(有虚假的营养价值):
现在,我们需要运行 reduce()方法。但是,它不能在一个值中被跟踪,我们想保留我们的类别。因此,我们的累加器需要是一个与数组具有相同类型的对象。
下面是这个过程的一个 GIF 图片:
在遍历数组每个项时,你将更改对象中特定属性的值,如果该对象尚未具有正确名称的属性,则将创建该对象,如下:
我们使用 bucket 作为对象,根据属性名对值进行分类。我们使用 += 操作符为来自 foods 数组的对象中的每个值添加到适当的 bucket。请注意保存值的 key 的名字,这里是随意的,这是因为它是无关紧要的——我们只是想要数字,这样我们就可以分析你一天饮食的成功。
如你所见,在我们的输出中有一个问题,结果包含一个 name 字段为“steak”,我们并不想存储该字段。因此,我们需要指定另一个参数——初始值。
这个参数在回调之后出现,我们希望将 calories、carbs 和 fat 字段初始化为 0,以便我们的 reduce 方法知道这是我们将用于 bucket 参数的唯一三个键 / 值对,代码如下:
原文:https://codeburst.io/javascri…
你的点赞是我持续分享好东西的动力,欢迎点赞!
一个笨笨的码农,我的世界只能终身学习!
更多内容请关注公众号《大迁世界》!