JAVASCRIPT IRL: Examples of JavaScript's ...

JAVASCRIPT IRL: Examples of JavaScript's filter function in real life

Jan 14, 2021

Bild

JavaScript array methods are super useful, and learning how to use them can really help improve the readability of your code. This is the third and final part of this series, and today I'll be discussing the filter function and how you can use it to make your code more concise. It's probably the easiest of the three to understand, since it's fairly straightforward, but it's always helpful to have examples on hand to understand exactly how it does and doesn't work.

Psst — don't have time to read through the entire article? Follow me on Instagram to get short, digestible posts on all things web development.

The filter function is called on an array and — like map — takes in one parameter: a callback. It performs this callback function on every element in the array, and includes the element in a new array if the callback returns true. Now, you might think that you can replicate this functionality without too much effort using map, but the key difference here is that map always returns an array with the same length as the original. (Well, almost always, but that's a bit more complicated and not really in the spirit of map to begin with.) On the other hand, filter will create an array that's only as large as the number of elements that pass the callback.

That may seem like a lot, but it honestly works just like you'd expect to. Let's take a look at a simple example:

A trivial example

Here, we add filter the array to only include all elements greater than 2:

        
      const arr = [1,2,3,4,5];
      const newarr = arr.filter(el => el > 2);

      console.log(newarr); // => [3,4,5]

The important thing to note here is that newarr is only of length 3; it doesn't return a null or undefined for the first two elements — it simply omits them entirely. We'll use this property to our advantage in the very next example.

Deleting caches (but properly this time)

If you've read my article on the map function, you'll recognize this example. However, it can still be improved: the null values that we returned could end up throwing an error later down the line. To avoid that, we're going to use filter to return an array that consists only of the elements that match the condition.

This is what it looks like:

        
      self.addEventListener('activate', e => {
        // Delete all caches that aren't named currentCache.
        e.waitUntil(
          caches.keys().then(cacheNames => {
            return Promise.all(cacheNames.filter(cacheName => {
              return cacheName !== currentCache;
            }).map(cacheName => {
              console.log('Deleting out of date cache:', cacheName);
              return caches.delete(cacheName);
            }));
          })
        );
      });

Again, very similar to the previous example. The key difference here is that before we map each cache to its delete function, we're filtering out all the caches that don't match our condition. That way, the currentCache won't appear in the array being passed to the map and thus we avoid any null values.

Let's look another example:

Filtering posts in a blog

On my blog page, I use a tagging system to allow users to filter content and view only the posts they're interested in. To do this, I actually created a JavaScript library called dynamic-tags. While creating it, I needed to find a way to take all of the posts on the page and only display the ones that matched the given filter.

While this could have devolved into a nasty mess of for loops and if statements, I used the filter function to make things both readable and efficient. Here's how it ended up:

        
      function filterPosts() {
        activePosts = posts;
        tagFilter.forEach(tag => {
          activePosts = activePosts.filter(post => tagDict[tag].includes(post));
        });
      }

Effectively three lines of code do much of the heavy lifting. In it, we go through each selected tag and call filter on activePosts to progressively remove any post that doesn't contain that tag. Even though filter might seem like a very minor abstraction over a plain for loop, we can see in this example just how concise and readable it makes your code.

Let's take a look at one final example:

Making things searchable

As an extension to the library I created above, I also wanted to create a system where users could search for topics and filter posts based on that. This is still a work in progress, but it already includes several useful examples of the filter function in action.

Let's take a look at my favorite one:

        
      populateSearchBox(el) {
        let searches = this.allTags.filter(tag => tag.toLowerCase().includes(el.childNodes[0].data.toLowerCase()));

        let searchBox = this.filter.querySelector(this.classListToSelector(this.searchBoxClass));
        if (searchBox) {
          searchBox = "";

          searches.forEach(search => {
            if (!this.tagFilter.includes(search)) this.addTagTo(search, searchBox, false);
          });
        }
      }

In this snippet, instead of filtering out posts, we're actually filtering out suggestions in the search box. Here, the filter function is used to ensure we're only appending suggestions that haven't already been selected. That is, we don't want a user to be filtering by topics that they've already filtered out.

The actual filter function is quite interesting — it looks for all the tags that contain the phrase inside the search bar. For example, given the tags ['May', 'June', 'July'], typing a 'y' into the search bar should return ['May', 'July']. On the other hand, typing 'J' should return ['June', 'July'].

Wrapping it up

And that's a wrap! I hope these examples gave you an idea of how the filter function is used in production, and how it can help make code more readable and versatile. Let me know in the comments if you've used the filter function in a cool way, and make sure to read the other two posts in the series if you haven't already!

As always, don't forget to follow me for more content like this. I'm currently writing on dev.to and Medium, and your support on either platform would be very much appreciated. I also have a membership set up, where you can get early previews of articles and exclusive access to a whole bunch of resources. Also, if you've particularly enjoyed this post, consider supporting me by buying me a coffee. Until next time!

Gefällt dir dieser Beitrag?

Kaufe Shailesh Vasandani einen cup of matcha

Mehr von Shailesh Vasandani