Guide to JavaScript's filter() Method

Guide to JavaScript's filter() Method

Introduction

Filtering through information is one of the most important tasks that we use automation/computers for! Computers and software wouldn't be nearly as useful if we had to sift through everything manually. By extension - filtering data for end-users is a common task, allowing users to narrow down the search space to a manageable level. JavaScript is the world's leading front-end language and the first frontier end-users see. Needless to say, the importance of filtering using JavaScript cannot be overstated.

In JavaScript, the filter() method allows us to filter through an array - iterating over the existing values, and returning only the ones that fit certain criteria, into a new array.

The filter() function runs a conditional expression against each entry in an array. If this conditional evaluates to true, the element is added to the output array. If the condition fails, the element is not added to the output array.

In this guide, we take a look at how to work with JavaScript's filter() method. First, we'll get acquainted with the method, its syntax, and arguments. Then, we'll go through several hands on examples of tasks that are easily tackled with the method. Finally - we'll compare it to an alternative method - find() and assess their performance.

Syntax and Parameter Values

The syntax is straightforward:

const filteredArray = oldArray.filter(callbackFn(element, index, array), context)


The callbackFn can be really any arbitraty function/predicate/criteria, as long as it returns a boolean value, based on the value of element. Technically, it doesn't have to utilize the element in its computation at all, but that most likely wouldn't be a very useful filtering function.

The index and array are optional, and you're not very likely to need to use array in practice. index is the index of the current item, and array is a pointer to the original array.

Note: The filter function constructs a new array and returns all objects that satisfy the criterion given in the callback. It doesn't change the underlying, original array.

How JavaScript's filter() Works

Let's take a look at the filter() method in action. In earlier versions of JS, prior to ES6 - a callback function would be used as:

const numbers = [20, 40, 17, 99, 59, 77];
const filteredNumbers = numbers.filter(function (number) {
return number > 20;
});

console.log(filteredNumbers); // [40,99,59,77]


Since ES6, we can simplify this as an arrow function:

const numbers = [20, 40, 17, 99, 59, 77];
const filteredNumbers = numbers.filter((number) => {
return number > 20;
});

console.log(filteredNumbers); // [40,99,59,77]


Or, you can collapse the function down into just:

const numbers = [20, 40, 17, 99, 59, 77];
const filteredNumbers = numbers.filter((number) => number > 20);
console.log(filteredNumbers); // [40,99,59,77]


How to Use the context Object with filter()

The filter() method can accept an additional, optional, context object:

filter(callbackfn, contextobj);


The object can be referenced using the this keyword from within the callback, and the context represents, well, whatever we pass in as the context for the filter. Let's take a look at an example!

We'll sort through a menu list, removing any items with prices that aren't between 15 and 25. The price range is a separate object, that we pass into the filter() as the context. In a sense - it's typically used to define a "configuration" object, containing values that we can generically access, without hard-coding them:

const menu = [
{
name: "buttermilk pancakes",
price: 15.99
},
{
name: "diner double",
price: 13.99
},
{
name: "godzilla milkshake",
price: 6.99
},
{
name: "country delight",
price: 20.99
},
{
name: "egg attack",
price: 22.99
}
];

let priceRange = {
lower: 15,
upper: 25
};


Now, let's filter() the menu list, passing in the priceRange as the context:

let filteredMenu = menu.filter(function (menu) {
}, priceRange);



This results in:

[
{
name:"buttermilk pancakes",
price:15.99
},
{
name:"country delight",
price:20.99
},
{
name:"egg attack",
price:22.99
}
]


How to Use the index Parameter

The index can be used to assess the position of an element in the original array. For instance, we could filter by the position of elements:

const users = ["John", "Doe", "Stephen", "Matt", "Abigail", "Susu"];

const topThree = users.filter((element, index) => {
return index <= 2;
});

console.log(topThree); // ["John", "Doe", "Stephen"]


While this could also be achieved by accessing the last N elements of an array, the index can play other roles and not be the sole criteria by which to filter.

How to Use the array Parameter

The array parameter references the original array we're filtering. Since you're iterating through the array anyway, you'll typically be satisfied without using the array parameter , but it can be useful if the logic depends on some state or property of the array itself:

const competitors = ["John", "Doe", "Stephen", "Matt", "Abigail", "Susu"];

function selectWinners(name, index, array) {

if (array.length > 3 && name.includes('a')) {
return true;
} else {
return false;
}
}

let lselectLoosers = competitors.filter((name, index, array) =>
selectWinners(name, index, array)
);

console.log(lselectLoosers); // ["Matt", "Abigail", "Susu"]


Another example could be if we want to get half of the elements of an array. In that case, we can use the original array to get the total elements to filter the elements based on the index value:

const halfArray = function (element, index, array) {
const half = Math.floor(array.length / 2);
return index < half;
};


We can now filter using halfArray:

const names = ["John", "Doe", "Stephen", "Matt", "Abigail", "Susu"];
const halfNames = names.filter(halfArray);
console.log(halfNames); // ["John", "Doe", "Stephen"]


In summary - the filter() method accepts a predicate function, that runs against every element in the array. Based on the boolean return value, the element is either placed or not placed in a new output array.

At the end of the iteration - only the resulting new array is returned, filtered by the criteria defined in the predicate function. A context object can be passed in, and is oftentimes used to define a "configuration" object that stores dynamic values used during filtering. The index refers to the position of the current element in the original array, and the array is a reference to the original array.

JavaScript's filter() Examples

With the introduction out of the way - let's dive into some practical examples of the filter() method.

Filter an Array of Objects by Value

Filtering an array of objects by some value they contain is one of the most common applications of the filter() method.

Dealing with Objects is not much different than working with other sorts of data types!

Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

For example, say we have an array of student objects, with a couple of fields. Say you'd also like to filter the students by those who graduated in the current year - the one obtaied by new Date().getFullYear().

You could easily compare the graduationYear of each element to the current year:

const students = [
{ firstName: "John", lastName: "Doe", graduationYear : 2022 },
{ firstName: "Stephen", lastName: "Matt", graduationYear : 2023 },
{ firstName: "Abigail", lastName: "Susu", graduationYear : 2022 }
];

const currentYear = new Date().getFullYear();

let graduatingStudents = students.filter((element) => {
return element;
}
});



This results in:

[
{
firstName:"John",
lastName:"Doe",
},
{
firstName:"Abigail",
lastName:"Susu",
}
]

Filtering Prime Numbers Using Array Filter In JavaScript

Let's continue with a simple excercise - filtering prime numbers! Let's define a list with a set number of integers, and then filter() it:

const myArray = [-7, -5, -2, 2, 1, 3, 12, 14, 13, 15, 70, 17, 33, 25, 27, 30, 97];

const primeNumbers = myArray.filter((element) => {
for (let i = 2; element > i; i++) {
if (element % i === 0) {
return false;
}
}
return element > 1;
});

console.log(primeNumbers); // [2, 3, 13, 17, 97]


You could, of course, also define a primeNumbers() function, that accepts an element and returns true or false based on whether the element is prime or not, and then use that method in the filter() call, if you'll be calling it multiple times over:

const numbers = [-7, -5, -2, 2, 1, 3, 12, 14, 13, 15, 70, 17, 33, 25, 27, 30, 97];

for (let i = 2; element > i; i++) {
if (element % i === 0) {
return false;
}
}
return element > 1;
}

console.log(numbers.filter(findPrimeNumbers)); // [2, 3, 13, 17, 97]

How to Filter Numbers From an Array

Filtering out numbers in an array, between other elements, is as easy as checking whether a variable is a number, and returning a boolean value:

const isNumber = function (element) {
return Number.isFinite(element);
};


We can now call our filter method with the resusable function:

const random = ['1', 'blue', 2, '-4', 0, true, -3.4 ];
const numbers = random.filter(isNumber);
console.log(numbers); // [2, 0, -3.4]


The method above isn't useful for numbers that are represented strings, so another method could be to first convert the element into a number if applicable (parseFloat()) and check the converted value with Number.isFinite():

const isNumber = function (element) {
return Number.isFinite(parseFloat(element));
};

const random = ['1', 'blue', 2, '-4', 0, true, -3.4 ];
const numbers = random.filter(isNumber);
console.log(numbers); // ["1", 2, "-4", 0, -3.4]


filter() vs find() array methods

It's worth taking a moment to appreciate what filter() is used for and what it's not used for. Filtering a list based on one or more criteria typically includes the return of a sublist, fitting the criteria - and more rarely, a single element, if the criteria is very strict. When you're looking for an element in a list - you'd filter out everything except the target element, returned in a list. A more natural fit for the latter is to find() the element, rather than filter() a list.

• filter() returns a list of all elements that "pass" the predicate
• find() returns the first object that "passes" the predicate

Suppose you have an array of menu with different categories:

  const menu = [
{
name: "buttermilk pancakes",
category: "breakfast",
price: 15.99,
status: "available"
},
{
name: "diner double",
category: "lunch",
price: 13.99,
status: "available"
},
{
name: "godzilla milkshake",
category: "shakes",
price: 6.99,
status: "available"
},
{
name: "country delight",
category: "breakfast",
price: 20.99,
status: "86"
},
{
name: "egg attack",
category: "lunch",
price: 22.99,
status: "available"
}
];


It's 8AM, and the restaurant serves only breakfast items until 10AM. You'll want to filter out the non-breakfast items:

let breakfastMenu = menu.filter((menu) => menu.category === "breakfast");


This results in:

[
{
name:"buttermilk pancakes",
category:"breakfast",
price:15.99,
status:"available"
},
{
name:"country delight",
category:"breakfast",
price:20.99,
status:"86"
}
]


Now, say someone's looking to order "country delight". The sublist is short enough for us to notice that it's 86'd, but with longer lists - we might want to check whether this item, when found, is available or not:

const delight = menu.find((menu) => menu.name === "country delight");

if (delight.status !== "86") {
console.log('Available!');
} else {
console.log('Sorry, the item is not available :(');
}


This results in:

Sorry, the item is not available :(


Using filter() with map()

The map() method is used to iterate through an array, and apply a function to each element, returning the result to a new array. It's a really common method, and chains with filter() well! For instance, let's filter out a few students, and then map the elements to their name and surname:

const students = [
{ firstName: "John", lastName: "Doe", grduationYear: 2022 },
{ firstName: "Stephen", lastName: "Matt", grduationYear: 2023 },
{ firstName: "Abigail", lastName: "Susu", grduationYear: 2022 }
];

.filter((element) => element.grduationYear === new Date().getFullYear())
.map((item) => {
return ${item.firstName}${item.lastName};
});

console.log(graduatingStudents); // ["John Doe", "Abigail Susu"]


Using filter() with indexOf()

The indexOf() method can be used to check whether a string starts with a substring, and conditionally return elements based on whether they do or don't. For instance, we could filter out a list of science courses, based on whether they start with "mth", signifying that those are math courses:

let sciCourses = ["Mth101", "Chm201", "Bio301", "Mth203", "Mth205"];
function checkCourses(courseArray, searchText) {
return courseArray.filter(function (item) {
return item.toLowerCase().indexOf(searchText.toLowerCase()) !== -1;
});
}
console.log(checkCourses(sciCourses, "mth")); // ["Mth101", "Mth203", "Mth205"]


Note: Again, since the filter() method does not mutate the original array, we need to save the filtered array to work with it later.

Conclusion

In this guide, we've taken a look at how JavaScript's filter() method works, and how we can use it to filter out elements from an array, given a predicate/certain filtering criteria. We've taken a look at the accompanying arguments, such as context, index and array that allow you to alter the predicate logic.

Finally, we've taken a look at several examples, and covered find() as an alternative for when you're only searching for a single element, and how filter() can be used with other methods in a chain.

Last Updated: March 7th, 2022

Get tutorials, guides, and dev jobs in your inbox.