Javascript 有人能解释一下这段代码吗

Javascript 有人能解释一下这段代码吗,javascript,Javascript,我得到了这段代码,但我无法得到r.concat部分,因为concat通常用于整个数组,而不是单个元素 function doubleOddNumbers(numbers) { return numbers.reduce((r, n) => n % 2 ? r.concat(n * 2) : r, []) } 以下是注释的代码: function doubleOddNumbers(numbers) { return numbers.reduce( // reduce iterate

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

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

以下是注释的代码:

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
}

以下是关于和的MDN文档。

我认为错误理解源于使用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
是一个数字。现在,reducer要么返回
r
本身,要么将
n*2
连接到数组,这也将导致一个数组传递到下一个reducer步骤

  [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
由于“numbers”是一个数组(由数字组成),您可以从数组的规格开始。此处的reduce函数:

每个reduce都是这样工作的:

arrayToReduce.reduce((memo, currentElement) => { /* operations using the currentElement that return the new memo value */}, initialValue);
发生了什么:

  • 从内存中的初始值(上面的初始值)开始,例如空数组

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

  • 函数返回的最后一个值是reduce操作的最终结果,即包含双倍奇数的数组


  • r
    是一个数组。这个代码很糟糕<代码>数字.filter(n=>n%2).map(n=>n*2)会更具可读性。
    .reduce((r,n)=>n%2?r.concat(n*2):r,[]/*@jonaswillms.TBF,我确实建议
    filter
    map
    ,我刚才在帖子上看到了OP的评论:),所以[]是acc的初始值。谢谢你的解释perfectly@ab2016D这个累加器将得到附加在它后面的奇数值的两倍。