Reputation: 33
I have got this block of code and I could not get the r.concat
part because concat
usually is used on a whole array not on a single element of it.
function doubleOddNumbers(numbers) {
return numbers.reduce((r, n) => n % 2 ? r.concat(n * 2) : r, [])
}
Upvotes: -1
Views: 70
Reputation: 356
As "numbers" is an array (of numbers), you can just start with the specification of the Array.reduce function here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
Every reduce works like so:
arrayToReduce.reduce((memo, currentElement) => { /* operations using the currentElement that return the new memo value */}, initialValue);
What happens:
You start with an initial value in memory (initialValue above) e.g. an empty array.
For each element of the array to reduce (e.g. arrayToReduce above), you execute a function which receives the current memorized value ("memo" above) and the current element in the array. The function will examine the current element and will compute a new memorized value. E.g. in your example, for odd numbers, you double the number and add it to the memorized array, then you return the memorized array; for even numbers you do nothing, so you return the memorized array unchanged.
The last value returned by the function is the eventual result of the reduce operation i.e. the array containing the odd numbers doubled.
Upvotes: 0
Reputation: 138537
I think the missunderstanding comes from this usage of reduce:
[1, 2, 3].reduce((a, b) => a + b, 0); // 6
In this example, both the value of the array b
, the accumulator a
and the initial value 0
are numbers. But it doesn't have to be like this, the accumulator and the arrays values can have different types. If we change the line above to:
[1, 2, 3].reduce((a, b) => a + b, "") // "123"
As the initial accumulator is an empty string, the first time reduce
executes it will concat "" + 1
, which will result in "1"
that gets passed to the next reduce step.
Now in your case, the initial accumulator value is an empty array.Therefore r
will be an array, whilst n
is a number. Now the reducer will either return r
itself, or it will concatenate n * 2
to the array, which will also result in an array passed to the next reducer step.
[1, 2, 3].reduce((acc, el) => acc.concat(el), [])
That said, the code shown is just a complete missuse of the .reduce
function. That you weren't able to understand the code does not mean that you are dumb, but it rather means that the code shown is badly written. I would write it as:
numbers
.filter(n => n % 2) // only.take odd numbers
.map(n => n * 2) // double them
Upvotes: 0
Reputation: 13983
Here is the code annotated:
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
}
Here is the MDN documentation on reduce and concat.
Upvotes: 1