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);
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);
1 Answer
Reset to default 10That 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 bees the callback (return) value of the iterations which follow.
If you want, you can backtrack and check the output.