我有这段代码,我无法得到r.concat
部分,因为concat
通常用于整个数组,而不是单个元素。
function doubleOddNumbers(numbers) {
return numbers.reduce((r, n) => n % 2 ? r.concat(n * 2) : r, [])
}
答案 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
}
答案 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);
会发生什么:
您从内存中的初始值开始(上面的initialValue),例如一个空数组。
对于要减少的数组的每个元素(例如,上面的arrayToReduce),执行一个函数,该函数接收当前存储的值(上面的“ memo”)和数组中的当前元素。该函数将检查当前元素并计算一个新的存储值。例如。在示例中,对于奇数,将数字加倍并将其添加到存储的数组中,然后返回存储的数组;对于偶数,您什么也不做,因此您可以不更改返回存储的数组。
该函数返回的最后一个值是reduce操作的最终结果,即包含奇数的数组加倍。