介绍
Reduce是一种很难理解的方法,尤其是在网络上可以找到的所有模糊的解释中。
JavaScript中的减少
数组方法的签名是:
1arr.reduce(callback, initialValue);
术语
Reduce 包含一些术语,如 reducer & accumulator. 蓄电器
是我们最终使用的值,而减少器
是我们执行的操作,以达到 one值。
您必须记住,一个 reducer只会返回一个值,而一个值只会返回名称 reduce。
举以下经典例子:
1const value = 0;
2
3const numbers = [5, 10, 15];
4
5for(let i = 0; i < numbers.length; i++) {
6 value += numbers[i];
7}
上面的结果会给我们30
(5 + 10 + 15)。这很好,但我们可以用减少
来做到这一点,这将使我们免受价值
变量的突变。
下面的代码也会输出30
,但不会改变我们的值
变量(我们现在称之为初始值
)
1/* this is our initial value i.e. the starting point*/
2const initialValue = 0;
3
4/* numbers array */
5const numbers = [5, 10, 15];
6
7/* reducer method that takes in the accumulator and next item */
8const reducer = (accumulator, item) => {
9 return accumulator + item;
10};
11
12/* we give the reduce method our reducer function
13 and our initial value */
14const total = numbers.reduce(reducer, initialValue)
上面的代码可能看起来有点困惑,但在帽子下面没有魔法发生. 让我们在我们的减速器
方法中添加一个console.log
,该方法将输出积累器
和项目
参数。
下面的屏幕截图显示了已登录到控制台的内容:
因此,我们注意到的第一件事是,我们的方法被称为3
次,因为我们的数组中有3
值。我们的积累器从0
开始,这是我们的初始值
,我们转到减少
。在每个函数调用时,项目
被添加到积累器
。该方法的最终调用具有积累器
值15
和项目
是15
,15 + 15
给了我们30
,这是我们的最终值。
所以这是一个简单的例子,你会如何使用减少
,现在让我们沉浸在一个更复杂的例子。
使用 Reduce 平面化一个 Array
假设我们有以下数组:
1const numArray = [1, 2, [3, 10, [11, 12]], [1, 2, [3, 4]], 5, 6];
让我们说出一些疯狂的原因,JavaScript已经删除了.flat
方法,所以我们必须自己平滑这个数组。
因此,我们会写一个函数来平衡任何数组,不管数组是多么深地嵌入:
1function flattenArray(data) {
2 // our initial value this time is a blank array
3 const initialValue = [];
4
5 // call reduce on our data
6 return data.reduce((total, value) => {
7 // if the value is an array then recursively call reduce
8 // if the value is not an array then just concat our value
9 return total.concat(Array.isArray(value) ? flattenArray(value) : value);
10 }, initialValue);
11}
如果我们将我们的numArray
传递到这个方法并记录结果,我们会得到如下:
这是我们如何使一个非常常见的操作相当简单的一个很好的例子。
让我们再来看看一个例子。
最后的例子 - 改变一个对象结构
因此,随着新款Pokemon游戏的发布,让我们假装我们有一个服务器,向我们发送一系列Pokemon对象:
1const pokemon = [
2 { name: "charmander", type: "fire" },
3 { name: "squirtle", type: "water" },
4 { name: "bulbasaur", type: "grass" }
5]
我们希望改变这个对象看起来像:
1const pokemonModified = {
2 charmander: { type: "fire" },
3 squirtle: { type: "water" },
4 bulbasaur: { type: "grass" }
5};
为了达到所需的结果,我们做以下操作:
1const getMapFromArray = data =>
2 data.reduce((acc, item) => {
3 // add object key to our object i.e. charmander: { type: 'water' }
4 acc[item.name] = { type: item.type };
5 return acc;
6 }, {});
如果我们这样称呼我们的方法:
1getMapFromArray(pokemon)
我们获得了我们想要的结果:
您可以查看此处的 Codesandbox)。
结论
乍一看,减少
看起来比其他JavaScript Array Iteration Methods
(LINK0
)更复杂,如map
和filter
,但一旦理解语法,核心概念和用例,它可以成为JavaScript开发人员的另一个强大工具。