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
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.
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:
- 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:
But there are still 2 problems with this function.
- 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) - 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
Let's invoke our myReducer function passing in the array of objects
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.
Let's test it again with the objects array.
First, declare the callback function and call myReduce
passing it in.
Note that we added if
and else
conditions based on the value of total
which is our initialValue option.
-
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
-
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:
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:
Create an array of unique categories for a restaurant menu
Given this array:
We need to reduce it into an array of unique categories like ['Appetizer','Entree','Main']
This is how we can do it:
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:
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:
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
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
Or we can do it with .reduce()
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:
This is our groupBy function:
It can get even handier if we add the option to pass the key
as a function.
Just replace this line:
With this one:
This way we can call it and pass a function that returns the key, as opposed to writing the string ourselves, avoiding typos.
How to flatten an array of arrays
This is a one-liner to flatten an array of arrays:
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)
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 π€
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.