I don't really understand what the reduce function is doing in this code

Tell us what’s happening:
The line I don’t really understand is: return args.reduce((a, b) => a + b, 0);

Where did a and b come from and how are they getting their values? How is the return value being calculated?

I’m sure it’s simpler than I think it is, but I feel like there’s some piece of information I’m missing.

  **Your code so far**

const sum = (x, y, z) => {
const args = [x, y, z];
return args.reduce((a, b) => a + b, 0);
}

console.log(sum(1,2,3))
  **Your browser information:**

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36

Challenge: Use the Rest Parameter with Function Parameters

Link to the challenge:

Yeah, reduce confuses a lot of people. It’s also really powerful once you get the hang of it.

reduce takes an array and “reduces” it to a single value.

Let me change the variable names and reformat a little:

args.reduce(
  (acc, cur) => acc + cur,  // callback function
  0                         // initial value
);

So, reduce starts with an initial value (0) and feeds each element of the array into the callback function. The callback function gets an “accumulator” and a “current element”. The cur is the current value of the array in this iteration. Whatever the callback returns becomes the new acc on the next iteration. At the end, the final value of the acc is returned from this method.

So, if our array is [12, 34, 56], then this what happens:

iteration 0:
  acc passed to CB: 0  // the initial value
  cur passed to CB: 12
  returned by CB: 12   // 0 + 12

iteration 1:
  acc passed to CB: 12 // returned from previous CB iteration
  cur passed to CB: 34
  returned by CB: 46   // 12 + 34

iteration 2:
  acc passed to CB: 46 // returned from previous CB iteration
  cur passed to CB: 56
  returned by CB: 102  // 46 + 56

The final result is going to be 102 because this is the final value returned by the callback.

But see for yourself. Good developers like taking things apart and seeing how they work:

const result = [12, 34, 56].reduce(
  (acc, cur, index) => {
    console.log('\niteration', index)
    console.log(' acc', acc)
    console.log(' cur', cur)
    const returnValue = acc + cur
    console.log(' returning', returnValue)
    return returnValue
  }, 0);

console.log('\nresult:', result)

Mess around with that and see how it works.

Incidentally, this is a case where you can leave off the initial value. If you don’t pass an initial value, it will just use the first element and skip to passing the second element to the callback. Mess around with that and see how it works.

3 Likes

Thanks for the explanation!

I had pasted the code into VB Code and tried going through with breakpoints after I made this post.

I managed to gleam that it was adding the values up using a and b, but I think my brain got really hung-up on the initial value, since I had no idea where the ‘0’ came from and hadn’t realised it’s purpose.

Also didn’t realise I could add console logs within that part of the function. I’ll have to start messing around with that from now on to see how I can use it to explain what’s happening.

1 Like

Hey, quick question about this.

What’s the purpose of breaking the function down when you write it?

It seems like it’s designed just for the purpose of adding numbers together. Why not just have arr.reduce or reduce(arr) instead of arr.reduce((a, b) => a + b, 0)?

Can it be used for other purposes as well by modifying what’s on the right of the =>?

I think this was the crux of my confusion, as it seems more complex than it is.

read this article this will give answer to you question.

1 Like

Well, reduce is not specific to summing numbers. All it is made for is taking an array, and reducing it to a single value. We do this by passing in a callback function. Of course, we could also store that callback in a variable. Here are some example uses of reduce. Mess around with them.

// numbers

const arr1 = [12, 4, -12, 3, 9]

const sum = (a, c) => a + c
console.log(arr1.reduce(sum))

const sumSquares = (a, c) => a + c**2
console.log(arr1.reduce(sumSquares, 0))

const product = (a, c) => a * c
console.log(arr1.reduce(product))

const getBiggest = (a, c) => a < c ? c : a
console.log(arr1.reduce(getBiggest))

const getSmallest = (a, c) => a < c ? a : c
console.log(arr1.reduce(getSmallest))

const getLargestSquare = (a, c) => (a < c) && (Math.sqrt(c) % 1) ? a : c
console.log(arr1.reduce(getLargestSquare, null))

// strings

const arr2 = ['cherry', 'grapefruit', 'apple', 'elderberry', 'banana', 'fig', 'date']

const getShortest = (a, c) => a.length < c.length ? a : c
console.log(arr2.reduce(getShortest))

const getShortestLength = (a, c) =>  c.length < a || !a ? c.length : a
console.log(arr2.reduce(getShortestLength, null))

const getAlphabeticalLast = (a, c) => a > c ? a : c
console.log(arr2.reduce(getAlphabeticalLast))

// boolean

const arr3 = [true, false, false, true, true, true, true, true, true]

const getCountTrue = (a, c) => a + +c
console.log(arr3.reduce(getCountTrue, 0))

const getCountFalse = (a, c) => a + +!c
console.log(arr3.reduce(getCountFalse, 0))

const getDiffFlagCount = (a, c) => a + (c ? 1 : -1)
console.log(arr3.reduce(getDiffFlagCount, 0))

That is just scratching the surface. It is really the most powerful prototype method - you can do what any of the others do and so much more. Actually, that’s a really good exercise, redoing other prototype methods like find, map, filter, etc.

1 Like

The MDN docs also have quite a few use case examples.

2 Likes

Ah, this makes the use cases clearer!

Thanks for the examples, and I’ll certainly play around with these exercises. Seems like it’s a well used function, so I think I need to make sure I understand it fully before moving on.

Thanks to everyone else as well for the reading material!

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.