Why does javascript's implementation of reduce skip execution for the first iteration?
[1,2,3].reduce((acc, val) => {
console.log('acc',acc);
console.log('val',val)
return acc + val;
});
// acc 1
// val 2
// acc 3
// val 3
// 6
I notice that the first statement execution never runs (in this case, I would have expected there to be 6 console logs, 2 for each element). This was very unexpected behavior when I was trying to execute a function with a side effect within each iteration with reduce.
In other languages that I've used, every iteration of the list passed executes. Are there examples otherwise?
Why does this happen and why is the implementation of javascript's native Array reduce like this?
========================= EDIT 1/Solution ========================
To make sure it goes through the first iteration, give it an initial value (the 2nd argument here/ 0 in this case)
[1,2,3].reduce((acc, val) => {
console.log('acc',acc);
console.log('val',val)
return acc + val;
}, 0);
The reduce() method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.
The reduce() method executes the function for each value of the array (non-empty array) from left to right. The reduce() method has the following syntax: let arr = [];arr. reduce(callback(acc, curVal, index, src), initVal);
accumulator is the value returned from the previous iteration. It will be initialValue for the first iteration.
Whenever you feel you are ready, go through the next steps on how to implement your custom reduce() : Initialize accumulator variable with 0 or initalValue argument from the reduce() . Loop through the array elements. Call the reducer function with the accumulator and current element as the arguments.
That is because of the fact that on every iteration, the first value is treated as a return
value (or the accumulator).
Straight from here, you can see
The accumulator accumulates the callback's return values; it is the accumulated value previously returned in the last invocation of the callback, or initialValue, if supplied (see below).
If we look at the source code here, we can see how it's implemented:
Array.prototype.myReduce = function(callback, initialVal) {
var accumulator = (initialVal === undefined) ? undefined : initialVal;
for (var i = 0; i < this.length; i++) {
if (accumulator !== undefined)
accumulator = callback.call(undefined, accumulator, this[i], i, this);
else
accumulator = this[i];
}
return accumulator;
};
In the else
structure, we can see that if the value is undefined
, we set it to the i-th
subindex in the array; which, for the first iteration, is the first one. After that, it becomes the callback (return) value of the iterations which follow.
If you want, you can backtrack and check the output.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With