1

The reduce method is still confusing to me. Why does

const sumOfCubes = nums => nums.reduce((a,b) => a + Math.pow(b, 3))

not work, but

const sumOfCubes = nums => nums.reduce((a,b) => a + Math.pow(b, 3), 0)

does?

ed'
  • 1,815
  • 16
  • 30
uber
  • 4,163
  • 5
  • 26
  • 55
  • 5
    If you don't supply the initial parameter, then `a` would be the *first* element from the array. Which means that with `[2, 3, 4]` the first operation will be `2 + Math.pow(3, 3)`. – VLAZ Dec 31 '19 at 16:37

2 Answers2

1

Because with reduce you should declare what the start/default value of the accumulator is. Which you are doing in the second example with passing 0 as an argument.

You can read more about it here:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

As suggested by @VLAZ, if you do not declare it will use the first element of the array and skip it:

InitialValue Optional A value to use as the first argument to the first call of the callback. If no initialValue is supplied, the first element in the array will be used and skipped. Calling reduce() on an empty array without an initialValue will throw a TypeError.

T. Short
  • 3,481
  • 14
  • 30
  • 2
    "*you need to declare what the start/default value of the accumulator is*" you don't **need** to do it. If you don't, then you'd get the first element of the array as the initial value. This *can* work but not always. – VLAZ Dec 31 '19 at 16:40
1

With only one argument, array.reduce(fn) is mostly the same as

for (let i = 1, a = array[0]; i < array.length; ++i)
  a = fn(a, array[i]);

Thus in your case the first value, 2, is never cubed, so you get the wrong sum.

With the second argument, it's like:

for (let i = 0, a = secondParameter; i < array.length; ++i)
  a = fn(a, array[i]);

Thus on the first iteration, the value to add is correctly 0 when you pass that as the second parameter, and each value in the array will be cubed.

Pointy
  • 405,095
  • 59
  • 585
  • 614