Reputation: 1218
reduce does not initialize accumulator to zero? Because the example below happens, I can not understand.
const r = (acc, curr) => acc |= (1 << curr);
let x;
x |= (1 << 0);
console.log(x); // -> 1 - OK
console.log([0].reduce(r)); // -> 0 - ???
And how do I get 1 correctly, as I expect, without doing something like this [0, 0].reduces(r);
.
Upvotes: 1
Views: 1825
Reputation: 1074178
No, reduce
doesn't default the accumulator. When you call reduce
with just one argument (the callback), the first call it makes to the callback uses the first entry as the accumulator and the second entry as the value to "add" to it. Of course, it can only do that when the array has at least two entries. When there's only one entry in the array and you don't provide an accumulator default, the entry's value is the result of reduce
(and your callback isn't called at all). That's why console.log([0].reduce(r));
gives you 0
. Finally, if you call reduce
on an empty array and don't provide a default, it's an error. (Which is why a.reduce((a, b) => a + b)
and a.reduce((a, b) => a + b, 0)
are not the same thing.)
Examples:
// Outputs 1 without calling the callback
console.log([1].reduce((acc, value) => {
console.log(`acc = ${acc}, value = ${value}`);
return acc + value;
}));
// Outputs 3 after calling the callback with acc = 1 and value = 2
console.log([1, 2].reduce((acc, value) => {
console.log(`acc = ${acc}, value = ${value}`);
return acc + value;
}));
let a = [];
// Throws an error
try {
console.log(a.reduce((a, b) => a + b));
} catch (error) {
console.error(error);
}
// Works
try {
console.log(a.reduce((a, b) => a + b, 0));
} catch (error) {
console.error(error);
}
.as-console-wrapper {
max-height: 100% !important;
}
Upvotes: 4