The JavaScript filter() Function

By

Learn how to use the JavaScript array filter() method to build a new array from elements that pass a test, a clean way to remove items from an array.

~~~

filter() is a very important method of an array.

It builds a new array containing only the elements that pass a test. You provide the test as a function: filter() calls it on every element, and when the function returns true, the element goes into the new array.

const prices = [3, 25, 40, 8, 12]
const affordable = prices.filter(price => price < 15)
// [3, 8, 12]

The original array is never touched. filter() always returns a new array:

prices
// [3, 25, 40, 8, 12]

How the callback works

The function you pass receives three arguments: the element, its index, and the whole array. Most of the time you only need the first one:

const cities = ['Rome', 'Milan', 'Florence', 'Venice']
cities.filter(city => city.length > 5)
// ['Florence', 'Venice']

The return value is evaluated as truthy or falsy, it doesn’t have to be a strict boolean. A nice trick built on this: pass Boolean as the callback to strip all falsy values from an array:

const values = [0, 'Flavio', '', null, 'Siena']
values.filter(Boolean)
// ['Flavio', 'Siena']

Removing items from an array

A good example of using filter() is when you want to remove an item from the array. You keep everything that is not the value you want gone:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(item => item !== valueToRemove)
// ["a", "b", "d", "e", "f"]

Here is how you could remove multiple items at the same time:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valuesToRemove = ['c', 'd']
const filteredItems = items.filter(item => !valuesToRemove.includes(item))
// ["a", "b", "e", "f"]

A common pitfall

filter() always returns an array, even when only one element can possibly match. If you use it to look up a single item, you get an array with one element and you have to unwrap it:

const books = [
  { id: 1, title: 'Ulysses' },
  { id: 2, title: 'Siddhartha' }
]

books.filter(book => book.id === 2)[0]
// { id: 2, title: 'Siddhartha' }

This works, but it scans the whole array even after finding the match, and the [0] at the end is easy to forget. Use find() for this case instead. It stops at the first match and returns the element directly, or undefined when nothing matches:

books.find(book => book.id === 2)
// { id: 2, title: 'Siddhartha' }

My rule of thumb: filter() when you want many elements, find() when you want one.

~~~

Related posts about js: