Build Your Own Filter

To better understand it

Apr 15 · 4 min read
Image for post
Image for post
Photo by Alex Block on Unsplash

Filtering is a common programming pattern in which we iterate over a set of elements and only return a new set of elements that pass the condition provided by a filter function. Unlike mapping, we cannot reverse the process of applying the filter function to get to the original dataset; however, this is possible to achieve in mapping via applying the reverse of the mapping function on the transformed set to get to the original one.

Applying filtering in the context of functional programming will help us achieve readability in a much better sense. All we have to do is provide the original array as well as the filtering function. With this declarative approach, the steps of filtering items from a set of data (array, in the case of this article) is hidden, and we have a focus on the end result we want to achieve.

Image for post
Image for post

For example in the picture above, we do provide the initial array of [🍕, 🍔, 🥗, 🍏] and the filtering function isHealthy. The filter iterates over each of these tasty foods and, based on the filtering function it has, decides which is healthy and which is not. Only the healthy ones will be preserved in the new array and, in the end, returned[🥗, 🍏].

Similar to mapping, we have a few options of filtering elements in an array, with both declarative and imperative approaches.

Using for loop for a filter is an imperative approach of iterating over elements and pushing the ones to an array that pass a condition nested in the for loop.

As you can see, we need to keep track of item indexes, define an initial array, and nest conditional statements inside the for loop. Even though this way of filtering can be performed, it is not very readable.


Another option we have is to use forEach, which, like a for loop, iterates over an array of elements. But the good thing about using it is we don’t have to worry about index tracking. Let’s see it with an example:

This seems like an improvement to the previous alternative in terms of readability, but mutating the result array outside the context of our iterator is not ideal. It would have been better if we had a filtering method that always returns a new array.

In fact, we have access to a better alternative, called a native JavaScript filter.

Native JavaScript Filter

Native JavaScript filter takes a declarative approach in filtering array elements. Since it is a method defined on Array.prototype, it iterates on a provided array and invokes a callback on it. This callback, which acts as our filtering function, takes three parameters:

  • element — the current item in the array being iterated over
  • index — the index or location of the current element in the array that is being iterated over
  • array — the original array that the filter method was applied on

Let’s use this filter method as an example. Note that the filter can be applied on any sort of array. In this example, we are going to filter an array of objects based on object property.

With just one line of code, we were able to filter an array of items. That is pretty awesome. Also, as you can see in line 12, chaining mapping and filtering methods can be really useful for working with different types of datasets.

So far, we have learned some basic stuff about filtering and different ways of handling it in JavaScript. Although our main focus was on readability, we should never forget performance when it comes to applying a method on our dataset.

Build a Filtering Function

We now turn our attention to building our own filtering functions. Building a production-ready filtering method that scales with larger datasets and considers different edge cases is not straightforward, as we can see in the polyfill made for JavaScript’s native filter. However, in our example, we’re going to focus on the core of filtering an array.

Own filter function (for loop version)

Abstracting the filtering process with for loop is very straightforward. We provide the filtering function and original array and let the FilterLoop handle the filtering process for us.

Own filter function (recursive version)

Now we are going to create a recursive version of the filtering function. Make sure to check to build a recursive version of a mapping function first.

Like the for loop version, we need to pass both an array as well as a filtering function. However, as you can see in line 2, we are destructuring the array parameter and breaking it apart into two new variables called head and tail.

This approach allows us to decide at each step if we need to return thehead element if it passes the validFn validation (shown on line 9). If not, we simply ignore the head the element for that iteration and continue recursively calling the FilterRecursive function (shown on line 13).

After each iteration, the length of the original array shrinks down until we reach an empty array in the end. It is at that point that head will be set as undefined, since we will be trying to destructure an empty array. Then we start returning array elements that passed the validator.

Own filter function (generator version)

This is a very rudimentary example of a filtering function built with generator functions. As you can see in the logs below the code, the generator function returns an iterator object each time it’s called. With passing our validator function, we are only returning values in the iterator object that passes its validation.

Better Programming

Advice for programmers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store