通过节食解释 JavaScript 的 Reduce 方法
如果您曾经阅读过营养标签,那么您就可以理解 JavaScript 中的 reduce() 方法。
JavaScript 中的 reduce 方法为您提供了一种简单的方法来获取一个值数组并将它们组合成一个值,或者根据多个类别对数组求和。
哇,一句话就说了这么多,所以让我们回顾一下。
当然,你始终可以使用for循环来遍历数组并对每个值执行特定的操作。但是,如果你不使用 filter()、map() 和 reduce() 等方法,你的代码将变得更难阅读。其他开发人员需要仔细阅读每个循环才能理解其目的。而且,由于你需要创建更多变量来跟踪单个值,这会增加出现 bug 的可能性。
过滤方法获取初始数组中的所有元素,并且只允许某些元素进入最终数组。
Map 方法在将初始数组中的每个元素存储到最终数组之前,对其运行一个函数。
而 reduce 方法将初始数组中的元素组合成最终值或值数组。
我意识到这有点像节食。从计算卡路里这种非常简单的方法,到像阿特金斯或慧俪轻体这样更复杂的节食方法,目标都是将你一天中可能吃的所有食物提炼成一个或多个数值,以此来判断你是否在减肥的轨道上。
那么,让我们开始吧!为了理解本教程,您只需要具备for循环的经验。
使用 For 循环模拟 Reduce
下面用 for 循环快速演示 reduce() 的功能。假设你有一个数组,里面存储了你一天吃过的 5 种食物的卡路里含量。你想计算出你总共摄入了多少卡路里。代码如下。
let calories = [800, 200, 100, 300, 700];
let total = 0;
for (let i = 0; i< foods.length; i++){
total += calories[i];
}
//value of total will be 2100
这很简单。你创建一个变量来保存最终金额,然后在遍历数组时将其添加到该变量中。但是,你仍然需要引入一个新变量,而且循环没有提供任何关于循环目的的线索。
Reduce 的一个简单示例
让我们学习如何使用 reduce() 方法实现相同的目标。
- Reduce 是一种数组方法,因此我们将从卡路里计数数组开始。
- 它使用在数组中的每个元素上运行的回调函数。
- 它使用返回语句来显示在数组每次迭代之后值应如何累积。
let foods = [800, 200, 100, 300, 700];
let total = foods.reduce(function(sum, item){
return sum + item;
});
所以,reduce有一些记忆的概念。当你遍历数组中的每个元素时,这些值都会被sum参数跟踪。在我们之前的例子中,我们必须在循环作用域之外声明一个新变量来“记住”这些值。
这和 for() 的可读性似乎没有太大区别。但是,当你(或其他开发人员)需要扫描数百行代码时,reduce 会给你一个关于代码块用途的快速提示。
示例 2- 使用对象
到目前为止,我们一直在讨论一维数组。但是,既然可以遍历一个全是数字的数组,那么也可以遍历一个全是对象的数组。让我们为每个元素添加一个名称,这样我们就能知道我们一天中到底吃了什么。
let foods = [
{name: 'steak', calories: 800},
{name: 'fruit', calories: 200},
{name: 'salad', calories: 100},
{name: 'chips', calories: 300},
{name: 'ice cream', calories: 700},
];
let total = foods.reduce(function(sum, item){
return sum + item['calories'];
}, 0)
//value of total will be 2100
你早餐吃了牛排……配了点水果……午餐吃了沙拉和薯条……最后晚餐吃了冰淇淋。这真是糟糕的一天。
希望您能理解我们遍历数组时的流程。随着我们遍历每个元素,总和会逐渐增加,最终代表一天消耗的总卡路里。关键在于将这些值放入一个大桶中——一天的卡路里摄入量。
示例 3-使用多个类别
那么,如果一切都与卡路里有关,那为什么会有这么多不同的饮食方案呢?我不想深入探讨营养科学,但这里总结一下:关于“最佳”减肥方法存在很多分歧。有些人鼓励你只计算卡路里,而另一些人则会考虑蛋白质、碳水化合物、脂肪以及其他各种因素。
假设你想修改代码,以便根据任何常见的饮食系统来评估你的饮食。你需要追踪每种食物的碳水化合物和脂肪含量。然后,你需要在最后汇总所有数据,以便计算出你在每个类别中摄入了多少克。以下是带有虚假营养价值的食物对象。
let foods = [
{name: 'steak', calories: 800, carbs: 10, fat: 30},
{name: 'fruit', calories: 200, carbs: 20, fat: 0},
{name: 'salad', calories: 100, carbs: 0, fat: 5},
{name: 'chips', calories: 300, carbs: 10, fat: 10},
{name: 'ice cream', calories: 700, carbs: 20, fat: 20},
];
现在,我们需要运行 reduce() 方法。但是,我们无法在一个值中跟踪所有内容。我们希望保留类别。因此,我们的累加器需要是一个与数组具有相同类别的对象。
这是该过程的简短 GIF。
每次执行时,你都会修改对象中特定属性的值。如果该对象还没有正确名称的属性,则需要创建它。代码如下。
let total = foods.reduce(function (buckets, item) {
let calories = item.calories;
let carbs = item.carbs;
let fat = item.fat;
buckets['calories'] += calories;
buckets['carbs'] += carbs;
buckets['fat'] += fat;
return buckets;
});
/*total object is
{name: 'steak', calories: 2100, carbs: 60, fat:65}
*/
我们使用buckets作为对象,根据属性名称对值进行分类。我们使用+= 运算符将对象中来自foods数组的每个值添加到相应的 bucket 中。注意到我们没有存储每种食物的名称吗?这是因为它无关紧要——我们只需要这些数字,以便分析你当天的饮食是否成功。
如你所见,我们的输出中有一个问题。我们有一个 name 字段被设置为“steak”。我们不想存储这个名称!所以,我们需要指定另一个参数——初始值。
此参数在回调之后传入,我们希望将卡路里、碳水化合物和脂肪字段初始化为 0,以便我们的 reduce 方法知道这三个键值对是 buckets 参数中唯一需要用到的。您可以在此处查看示例。
let total = foods.reduce(function (buckets, item) {
let calories = item.calories;
let carbs = item.carbs;
let fat = item.fat;
buckets['calories'] += calories;
buckets['carbs'] += carbs;
buckets['fat'] += fat;
return buckets;
},
{calories: 0, carbs: 0, fat:0}
);
/*total object is
{calories: 2100, carbs: 60, fat:65}
*/
获取最新教程
你喜欢这个教程吗?查看CodeAnalogies 博客,获取最新的 HTML、CSS 和 JavaScript 主题可视化指南。
鏂囩珷鏉ユ簮锛�https://dev.to/kbk0125/javascripts-reduce-method-explained-by-going-on-adiet-3078