JavaScriptReduce方法解释

来自菜鸟教程
跳转至:导航、​搜索

介绍

Reduce 是一种很难理解的方法,尤其是在网络上可以找到所有模糊解释的情况下。 理解 reduce 有很多好处,因为它经常用于状态管理(想想 Redux)。

JavaScript 中 reduce 数组方法的签名是:

arr.reduce(callback, initialValue);

术语

Reduce 附带一些术语,例如减速机和蓄能器 . accumulator 是我们结束的值,reducer 是我们为了得到 一个值 将执行的操作。

您必须记住,reduce 只会返回一个值,并且只返回一个值,因此名称为 reduce

举一个经典的例子:

const value = 0; 

const numbers = [5, 10, 15];

for(let i = 0; i < numbers.length; i++) {
  value += numbers[i];
}

以上将给我们 30 (5 + 10 + 15)。 这工作得很好,但我们可以用 reduce 来代替,这将使我们免于改变我们的 value 变量。

下面的代码也会输出 30,但不会改变我们的 value 变量(我们现在称之为 initialValue

/* this is our initial value i.e. the starting point*/
const initialValue = 0;

/* numbers array */
const numbers = [5, 10, 15];

/* reducer method that takes in the accumulator and next item */
const reducer = (accumulator, item) => {
  return accumulator + item;
};

/* we give the reduce method our reducer function
  and our initial value */
const total = numbers.reduce(reducer, initialValue)

上面的代码可能看起来有点混乱,但实际上并没有什么神奇之处。 让我们在 reducer 方法中添加一个 console.log,它将输出 accumulatoritem 参数。

以下屏幕截图显示了记录到控制台的内容:

所以我们注意到的第一件事是我们的方法被调用了 3 次,因为我们的数组中有 3 值。 我们的累加器从 0 开始,这是我们传递给 reduceinitialValue。 在每次调用该函数时,item 被添加到 accumulator。 对方法的最终调用具有 15itemaccumulator 值是 1515 + 15 给我们 [X122X ] 这是我们的最终值。 请记住 reducer 方法返回 accumulator 加上 item

以上就是如何使用 reduce 的简单示例,现在让我们深入研究一个更复杂的示例。

使用 Reduce 展平数组

假设我们有以下数组:

const numArray = [1, 2, [3, 10, [11, 12]], [1, 2, [3, 4]], 5, 6];

假设出于某种疯狂的原因,JavaScript 删除了 .flat 方法,所以我们必须自己扁平化这个数组。

因此,我们将编写一个函数来展平任何数组,无论数组嵌套有多深:

function flattenArray(data) {
  // our initial value this time is a blank array
  const initialValue = [];

  // call reduce on our data
  return data.reduce((total, value) => {
    // if the value is an array then recursively call reduce
    // if the value is not an array then just concat our value
    return total.concat(Array.isArray(value) ? flattenArray(value) : value);
  }, initialValue);
}

如果我们将 numArray 传递给此方法并记录结果,我们将得到以下结果:

这是一个很好的例子,说明我们如何使一个非常常见的操作变得非常简单。

让我们再看一个例子。

最后一个示例 - 更改对象结构

因此,随着新 Pokemon 游戏的推出,让我们假设我们有一个服务器向我们发送一系列 Pokemon 对象,如下所示:

const pokemon = [
  { name: "charmander", type: "fire" },
  { name: "squirtle", type: "water" },
  { name: "bulbasaur", type: "grass" }
]

我们想改变这个对象看起来像:

const pokemonModified = {
  charmander: { type: "fire" },
  squirtle: { type: "water" },
  bulbasaur: { type: "grass" }
};

为了获得所需的输出,我们执行以下操作:

const getMapFromArray = data =>
  data.reduce((acc, item) => {
    // add object key to our object i.e. charmander: { type: 'water' }
    acc[item.name] = { type: item.type };
    return acc;
  }, {});

如果我们这样调用我们的方法:

getMapFromArray(pokemon)

我们得到了我们想要的输出:

你可以在这里查看代码沙盒。

结论

乍一看,reduce 看起来比 mapfilter 等其他 JavaScript 数组迭代方法 更复杂,但是一旦语法、核心概念和使用-cases 可以理解为 JavaScript 开发人员的另一个强大工具。