Simplify your code using .reduce(), .map() and .filter()

Tram Ho

If you’ve just started coding in JavaScript for a short while, you’ve probably only heard of .map() , .reduce() and .filter() but haven’t really used it much. For me, it took a while because I code for a Japanese company . So I have to code how to be able to support Internet Explorer 8 and some older browsers (mainly the maintenance project, the rest is all ES6.). So if you don’t need to code something that needs to be compatible with these very old browsers, then you have to be familiar with functions like .map() , .reduce() and .filter() it will help you a lot.

Opening example: this groupBy function is just a few simple lines and it is too convenient to group + filter If you go through this article, I think you can also code a function like that

Result: Another special feature is that the difficulty of this algorithm is (On) too good

Note that this article will most likely apply to any other programming language you may be using, as these are concepts that exist in many other languages.

OK HATE

.map()

Let me explain how it works with a simple example. Let’s say you received an array containing many objects – each object represents a person. However, what you really need in the end is an array containing only the id of each person.

There are many ways to achieve this. You might want to do that by creating an empty array, then using .forEach() , .for(...of) or simply .for() to achieve your purpose.

Let’s compare ways to do it!

Using .forEach() :

Notice this way you have to create an empty array first? Next, let’s see what it looks like using .map() :

We can be even more concise with arrow functions (Note: ES6, Babel or TypeScript)

So how does .map() work? Basically there are 2 arguments, a callback function and an optional contexts (default will be this in the callback function) that I didn’t use in the previous example. The callback function will be called for each value in the array and return each new value in the resulting array.

Remember that the resulting array will always be the same length as the original array.

.reduce()

Like .map() , .reduce() also calls the callback function for each element of the array. What’s different here is that reduce passes the result of this callback to an bộ tích lũy from one array element to another.

The accumulator can be anything (integer, string, object, etc) and must be initialized or passed in when .reduce() called.

Time to do some examples to make it easier to understand! Let’s say you have a list of pilots and their respective years of experience:

We need to know the total years of experience of all of them. With .reduce() , it’s pretty simple:

Note that I have set the starting value to 0 . I can also use an object if needed. After calling the callback for each element of the array, reduce will return the final value of our bộ tích lũy (in this case: 82 ).

And of course it can also be shortened with ES6 arrow functions:

Now, suppose we want to find out which pilot is the most experienced. For this question, I could also use reduce :

I named my bộ tích lũy oldest . My callback function compares the accumulator with each pilot. If a pilot has more years of experience than oldest , then that pilot will become the oldest pilot and eventually I will return oldest .

As you can see, using .reduce() is an easy way to create a value or an Object from an array.

.filter()

What if you have an array, but only want some elements in it? That’s when you need to use .filter()

Here is our data:

Suppose now we want to have two arrays: one is for the “Rebels”, the other is for the “Empire” piece. With .filter() it’s simply useless!

And it’s even shorter with arrow functions:

Basically, if the callback function returns true , the current element will be in the resulting array . If it returns false , it will not be included in the results list.

Go to the good part about combining .map(), .reduce() and .filter()

Since all three are called on arrays, and since .map() and .filter() both return arrays, we can easily chain our calls.

Let’s see another example. Here is our data:

Our goal is: just get the total score of the users whose isForceUser is true . Let’s do it step by step!

First, we need to filter out the user for which isForceUser is false :

After filtering, we have 3 elements left in our resulting array. Now we need to create an array containing the total score of each Jedi .

And let’s use reduce to get the total:

And now the fun part… we can chain all of this to get what we want in a single line:

And see how concise it is if used with arrow functions:

Boom! It’s so cool, isn’t it much easier to understand in a shorter way

Note: In the above example, .map() and .filter() are not even needed. We can easily achieve the same result with just .reduce() . However, in the above example, I still use it for you to better visualize. Can you guess how just using .reduce() and still get the same result with just one line of code?

Ten ten easy is right:

Why not use .forEach()?

Great question, actually I used to use for loops everywhere instead of .map() , .reduce() and .filter() . But recently, when I had the opportunity to write the function bases myself for my current project, I started working more with the data coming from the API. That’s when I started to see the advantages of using them. As you can see in the first example I gave, you can completely solve a problem with just 1 line of code.

Formatting

Let’s say you have a list containing name and title :

The API gives you the above data, but you only need the title and last name of each person… Since we have the fullname, we must format it right? (firstname + lastname) So you have to write a data format function to use every time we loop.

That means you can’t have a .forEach loop inside the formatElement function, otherwise you’ll have to wrap your single element in an array before passing it to the function just for it to work, like this:

So your loop must end the call of the function, like this:

But .forEach() doesn’t return anything. That means you have to push the result inside a pre-declared array.

As a result you have 2 functions: the formatElement() function and the function that push the result into your array.

Why have 2 functions when you only need 1 is enough:

Testing is easier

If you write unit tests for your code, you will find it simpler to test functions with .map() , .reduce() or .filter() .

All you have to do is feed the function data and expect the results to appear. Basically “what if this is passed ?”. Fewer operations, less beforeEach() and afterEach() . It will be a lot simpler.

Try to replace some of your for loops with .map() , .reduce() , .filter() where it seems appropriate. I guarantee your code will be less cluttered and much easier to read.

In the past, when I first used these functions, especially .reduce() , I was also very confused but gradually I will get used to it.

Roundup

As always, I hope you enjoyed this article and learned something new.

Thank you and see you in the next posts!

If you find this blog interesting, please give me a like and subscribe to support me. Thank you.

Ref

Share the news now

Source : Viblo