任何人都可以解释以下代码段:

时间:2019-05-08 17:08:43

标签: javascript

我有这段代码,我无法得到r.concat部分,因为concat通常用于整个数组,而不是单个元素。

function doubleOddNumbers(numbers) {
  return numbers.reduce((r, n) => n % 2 ? r.concat(n * 2) : r, [])
}

3 个答案:

答案 0 :(得分:1)

这是注释的代码:

function doubleOddNumbers(numbers) {
  return numbers.reduce( // reduce iterates over numbers and passes an accumulator from iteration to iteration
    (r, n) => // the reducer function called for each element, r is the accumulator, n is the element
      n % 2   // if the element is odd
        ? r.concat(n * 2) // then append its double to the accumulator
        : r   // otherwise return the accumulator unchanged
  , [])       // start with an empty array for the accumulator
}

这是reduceconcat上的MDN文档。

答案 1 :(得分:0)

我认为误解来自于reduce的这种用法:

 [1, 2, 3].reduce((a, b) => a + b, 0); // 6

在此示例中,数组b的值,累加器a和初始值0都是数字。但这不必一定是这样,累加器和数组值可以具有不同的类型。如果我们将上面的行更改为:

 [1, 2, 3].reduce((a, b) => a + b, "") // "123"

由于初始累加器为空字符串,因此reduce第一次执行时将连接"" + 1,这将导致"1"传递到下一个reduce步骤。

在您的情况下,初始累加器值是一个空数组。因此,r将是一个数组,而n是一个数字。现在,化简器将自己返回r,或者将n * 2连接到数组,这还将导致将数组传递到下一个化简器步骤。

  [1, 2, 3].reduce((acc, el) => acc.concat(el), []) 

也就是说,显示的代码只是对.reduce函数的完全误用。您无法理解该代码并不意味着您很愚蠢,而是意味着所显示的代码编写不正确。我将其写为:

  numbers
     .filter(n => n % 2) // only.take odd numbers
     .map(n => n * 2) // double them

答案 2 :(得分:0)

由于“数字”是一个(数字)数组,因此您可以从Array.reduce函数的规范开始:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

每个reduce的工作方式如下:

arrayToReduce.reduce((memo, currentElement) => { /* operations using the currentElement that return the new memo value */}, initialValue);

会发生什么:

  1. 您从内存中的初始值开始(上面的initialValue),例如一个空数组。

  2. 对于要减少的数组的每个元素(例如,上面的arrayToReduce),执行一个函数,该函数接收当前存储的值(上面的“ memo”)和数组中的当前元素。该函数将检查当前元素并计算一个新的存储值。例如。在示例中,对于奇数,将数字加倍并将其添加到存储的数组中,然后返回存储的数组;对于偶数,您什么也不做,因此您可以不更改返回存储的数组。

  3. 该函数返回的最后一个值是reduce操作的最终结果,即包含奇数的数组加倍。