DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

SavagePixie
SavagePixie

Posted on

Understanding reduce in JavaScript

When I first started learning JavaScript, I had some trouble grasping reduce(). I have heard of other people having trouble with it when they started as well. So I decided to write an overview of how it works hoping that it might help someone else.

What it does

reduce() is a method that you can use with any array. It iterates over every element and returns one single result based on its operations. These operations depend on a parameter called reducer, which is a callback function that we provide for the reduce() method.

What on earth is 'a'?

The thing that really confused me about reduce() was a. But what is a? If you look for examples of code using reduce() online, you are likely to find things such as this.

const arr = [ 1, 2, 8, 14 ]
const sum = arr.reduce((a, b) => a + b)

I would look at stuff like that and tell myself, Okay, I understand that a and b are supposed to be elements in the array, but how on earth does JavaScript know which one is which? and how is the result of this that they all get added up? And that's an easy example. Then you see things like this one.

const arr = [["potatoes", 3], ["tomatoes", 85], ["onions", 27]]
const result = arr.reduce((a, b) => {
  a[b[0]] = b[1]
  return a
}, {})

Now, this is just bonkers. What on earth is that {} as last parameter? What is this even doing?

Well, let's look at what this a means (or any other argument name in that position, for that matter, it needn't be a.) reduce()'s syntax is as follows:

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initial value])

Our callback function takes between two and four parametres.

  • accumulator this is the a in our previous examples. It is a variable where reduce() stores the result of each iteration over the array.
  • currentValue that's the name we'll use to call each element within the array.
  • index the index of currentValue (optional.)
  • array the whole array over which we are iterating (optional.)

The enlightening moment, for me, was realising that a is the place where reduce() stores the information of the previous iterations. So when we add stuff to it, we're keeping it safe until the end of the execution.

Let's analyse the first example

const arr = [ 1, 2, 8, 14 ]
const sum = arr.reduce((a, b) => a + b)

Here, our callback function adds up the current element with the accumulated value and that's what becomes the new accumulated value. Since there is no initial value passed as an argument, it will use the first element instead and skip running through it. So reduce() will do the following:

  1. a = 1, b = 2
    • 1 + 2 = 3
    • a becomes 3
  2. a = 3, b = 8
    • 3 + 8 = 11
    • a becomes 11
  3. a = 11, b = 14
    • 11 + 14 = 25
    • a becomes 25
  4. reduce() returns 25, which is assigned as the value of sum.

Let's look at the second example

const arr = [["potatoes", 3], ["tomatoes", 85], ["onions", 27]]
const result = arr.reduce((a, b) => {
  a[b[0]] = b[1]
  return a
}, {})

This one is a bit more complex, because the operation isn't as simple and because we're initialising a as an empty object. Our reducer function takes a two-dimensional array with sets of key and value and turns it into an object. Let's look at what is going on in more detail

  • a is an empty object.
  • a[b[0]] = b[1] creates a new property in the object and assigns the value of the second index in the deep array to it.
  • The function returns a; whatever is returned by our reducer function becomes the new accumulated value.
  1. a = {}
  2. a.potatoes is created and assigned a value of 3; a = { potatoes: 3 }
  3. a.tomatoes is created and assigned a value of 85; a = { potatoes: 3, tomatoes: 85 }
  4. a.onions is created and assigned a value of 27; a = { potatoes: 3, tomatoes: 85, onions: 27 }

Conclusion

reduce() is a powerful method that can be used to transform data in an array in many ways. It can be a bit confusing at the beginning. But for me, the trick was to understand that the result of each run of the callback function will be stored in the first argument it takes, this little a or accumulator.

Top comments (11)

Collapse
angelfire profile image
AndrΓ©s Bedoya

That's why it's important use well named variables, imagine that your first approach with reduce was this way:
arr.reduce((accumulator, currentValue) => accumulator + currentValue);

Much better, don't you think so? It's almost self explanatory...

Collapse
savagepixie profile image
SavagePixie Author

I'm pretty sure I would still have found a way to be confused by it, hahaha

But I do agree that clear naming goes a long way to help understand code.

Collapse
chrisidakwo profile image
Chris Idakwo

This is still confusing to someone who has never worked with reduce(). But then makes explaining it a bit more easy.

Collapse
htissink profile image
Henrick Tissink

This is a great post - really well written and clear; it removes all the confusion surrounding reduce. Thanks Pixie! :]

Collapse
mshirlaw profile image
Matt Shirlaw

Nice explanation, well done πŸ‘

Collapse
pinz88 profile image
Matthew Pinzino

This was awesome, thanks for the article.

Collapse
toddcoulson profile image
Todd Coulson

"I understand that a and b are supposed to be elements in the array, but how on earth does JavaScript know which one is which?"

I don't understand any of these questions you were asking when first analyzing reduce. First a and b were not elements in an array, but rather parameters, that is how they are figured out which are which. The person asking those questions, don't understand the difference between functions and arrays.

Collapse
savagepixie profile image
SavagePixie Author

Well, b is an element of the array in the sense that it represents the element currently being processed in the array. Even MDN speaks of it that way (and even a would be an element in the array for the first invocation of the callback function in that particular case.)

At any rate, I think the root of our misunderstanding is that you seem to be taking my words as talking about their syntactic function (so to speak), while I'm talking about the value they represent and how reduce() deals with them.

Collapse
hongphuc5497 profile image
Hong Phuc

Thanks, sometimes I forget how to use the function and topic like this is so helpful

Collapse
andrewyhchan994 profile image
Andrew Chan

Hi, where would the semicolons be placed in example 2?

Collapse
iglesfe profile image
Federico Iglesia • Edited on

holy s**t!!! it's so clear now, thank you!!

🌚 Life is too short to browse without dark mode