DEV Community

Gus Pear 🍐
Gus Pear 🍐

Posted on • Edited on

The Complete Guide To JavaScript's .reduce() Function (With Real-world Examples)

In this guide we are going to cover:

  • What is the .reduce() function?
  • Creating our version of the .reduce() function
  • Calculating the total items and price for a e-commerce shopping cart
  • Creating an array of unique categories for a restaurant menu
  • Removing duplicate objects from the array
  • Replacing .filter().map() with .reduce()
  • Grouping objects by key (Similar to SQL GROUP BY or C#'s .GroupBy())
  • How to flatten an array of arrays

Link for all code snippets used in this guide

It seems confusing at first

If you have ever struggled to understand the .reduce() function, you are not alone. It takes messing about with it a couple of times to really understand how it works and use it with confidence.

Most of the examples out there use a simple array of numbers or strings, but the reality is that we normally work with complex objects which is rarely covered.

But before we jump in.
Here's how you can get more out of this content.

  • Open your code edtitor and try the examples yourself
  • tinker with it (alter values, add or remove elements to/from the array, etc)
  • If you find yourself lost in one of the examples, track down the value of the variables either with a pen and paper or on your code editor.

Let's get started!

What is the .reduce() function?

It is a method that executes a callback function on each element of an array.

  • The return value from the calculation is passed on to the next element.
  • In the first iteration, there is no "return value of the previous calculation", if passed in, a initial value can be used in it's place.
  • Otherwise, the first element of the array is used as the initial value and iteration starts from the next element.

To put it simply, it is just a variable and a loop.

  • The variable holds the new value
  • The loop iterates over the array so we can grab what we want from each element

This:
Image description

Achieves the same as this:
Image description

Pretty much every time you need to use a variable and a loop, you can replace it with the reduce function.

As there is no better way of learning than actually trying things out, let's build our version of the .reduce() method so we can really understand it.

Building our own .reduce()

Let's do it by solving a simple problem:
We have an array of numbers and we want the sum of all of them.

It is just like the example above of a variable and a loop.

Image description

We need 3 things:

  • an array
  • a variable that holds the total value total(usually called the accumulator)
  • a loop to iterate over the array

Let's say you want to turn it into a function so you can use it easily, how would you do it?

Maybe something along these lines:

Image description

  • We pass the array as a parameter into our function
  • We return total at the end.

That is looking good, but what if we want the option to set the initial value of the variable total?
We can add the option as another parameter and set total to its value.

Like so:

Image description

But there are still 2 problems with this function.

  1. There is no way we can add different logic to be executed inside the loop (It only adds the current element to the sum variable)
  2. It works only on simple arrays (where each item is a value type, not an object)

I'll show you what I mean.

Let's create an array of objects this time

Image description

Let's invoke our myReducer function passing in the array of objects

Image description

It doesn't work because the value we want to add is inside the object and not the object itself.
We have to access it as total += arr[i].number

But this function didn't account for that.

However, if we add a callback function as a second parameter, we can:

  • Execute the callback function on each element of the array
  • Create any custom logic we need

Let's modify our myReducer function.

Image description

Let's test it again with the objects array.

First, declare the callback function and call myReduce passing it in.

Image description

Note that we added if and else conditions based on the value of total which is our initialValue option.

  1. If initialValue is not given

    • it doesn't execute the callback on 1st iteration
    • There is nothing to add, initialValue is undefined.
    • just set total to the value of the current element
  2. If initialValue is given

    • It executes the callback on all iterations

That is pretty much what the original Array.prototype.reduce() does.

The main difference is that there's no need to pass the array as an argument as the original .reduce() is bound to Array.prototype so the array is always the array upon which .reduce() was called.

Calculate total items and price for an ecommerce shopping cart

Say you have an array like this one:

Image description

And you need to reduce this array into an object like this { totalItems: 0, totalPrice: 0 } so we can display the correct information on the checkout page.

This is how we can do it:

Image description

Create an array of unique categories for a restaurant menu

Given this array:

Image description

We need to reduce it into an array of unique categories like ['Appetizer','Entree','Main']

This is how we can do it:

Image description

Removing duplicate objects from the array

Similar to the example above, but this time we need to return the same array of objects filtered with only unique objects.

This is the array with a duplicate object:

Image description

Note: You have to have a property similar to id that is unique for each object

This is how we can create another array with only unique elements:

Image description

Replace .filter().map() with .reduce()

It's very common having to filter an array and then modify the elements of the filtered array.

We will use the same array of the menu categories above

Image description

But this time we want to get an array with the itemName only of the items whose category is 'Entree'

We can use .filter() the array and then .map() to accomplish it

Image description

Or we can do it with .reduce()

Image description

The advantage of using .reduce() is that you iterate over the array only once.

Group objects by key (Similar to SQL GROUP BY or C#'s .GroupBy())

This is the one I like the most. This is a very handy function that will be included in JavaScript's array methods in probably on next update (currently on stage 3 for approval)

This groupBy function can also be used as a middle step to solving more complex problems.

We again will use the menu categories array:

Image description

This is our groupBy function:

Image description

It can get even handier if we add the option to pass the key as a function.

Just replace this line:

Image description

With this one:

Image description

This way we can call it and pass a function that returns the key, as opposed to writing the string ourselves, avoiding typos.

Image description

How to flatten an array of arrays

This is a one-liner to flatten an array of arrays:

Image description

Note: It only works with one level of nesting. For multiple levels you have to write a recursive version.

Conclusion

In this article we have learned:

  • What is the .reduce() function
  • How to create our version of the .reduce() function
  • To calculate the total items and price for an e-commerce shopping cart
  • To create an array of unique categories for a restaurant menu
  • To remove duplicate objects from the array
  • To replace .filter().map() with .reduce()
  • How to group objects by key (Similar to SQL GROUP BY or C#'s .GroupBy())
  • How to flatten an array of arrays

Thanks for reading!

If you like this article:

  • Leave a comment below
  • Follow me on Twitter @theguspear for more content like this one.

Catch you later,

Gus.

Top comments (2)

Collapse
 
bcostaaa01 profile image
Bruno

Wow! This is such a concise, clear and well-explained article!πŸ‘Thank you very much for sharing your thoughts with the community, @gustavupp!

The only thing I would point out would be the code snippets from Dev.to you could have made use of 🀭

Collapse
 
gustavupp profile image
Gus Pear 🍐

Hey Bruno, thanks for your comment and Happy new year !!
I was just editing now and added a link to my github repo with all the code snnipets.
I really aprreciate your feedback.