Filtering a list of items in an array is a common process any JavaScript developer, whether they are new or experienced, will use at some point in their career. Thankfully, arrays in JavaScript come with a built-in method called filter()
, which we are going to explain how to use in this article.
Table of Contents
How The Array Filter() Method Works
The array filter method creates a new array of elements based on elements of the original array that pass a logical condition or test function defined in a callback function. The array filter method concept might sound confusing when reading it for the first time, but it doesn’t have to be. To make things more clear, let’s look a the following image.
As you see in the previous image, we have an array of geometrical shapes: there are triangles, squares, and circles with different colors. Let’s say we are only interested in getting triangles from that array. Hence, we use the filter method to define the conditions of those elements we want to keep inside. As a result, we get a list of elements filtered. Notice how a new array is created instead of replacing the original array.
How to Use the Array Filter Method
Now that you understand the behavior of the filter()
method and its final result, we are going to learn how to use the filter()
method in JavaScript.
Note: Remember: the filter()
method will be available as long as there is an array instantiated.
Understanding the Syntax
First, let’s understand the syntax of the filter()
method. The filter method accepts two arguments, a callbackFn
and thisArg
or the value of this
inside the callback function. We are going to explain later thisArg
argument to keep things simple.
// filter() method syntax
filter(callbackFn)
filter(callbackFn, thisArg)
As you noticed, there are two syntaxes to use the filter()
method. Using the callbackFn
argument is required. Using the thisArg
is optional. Hence, it is enough if we only provide the callbackFn
parameter.
The callbackFn
is a callback function that accepts up to three parameters: element
, index
, array
.
// filter callback function syntaxes
function(element) { ... }
function(element, index) { ... }
function(element, index, array){ ... }
Let’s understand what each of these parameters is:
- The
element
is the current element in the original array (required parameter). - The
index
is the position of theelement
or current element in the original array (optional parameter). - The
array
is the original array (optional parameter).
This leaves us with four different syntaxes you can use when using the filter()
method.
// filter() method syntax
filter(function(element) { ... });
filter(function(element, index) { ... });
filter(function(element, index, array){ ... });
filter(function(element, index, array) { ... }, thisArg);
Using the filter()
Method without thisArg
It is typical to use the filter()
method without the thisArg
. Let’s look at how to use filter()
method without it.
- First, create an array that we are going to use the
filter()
method.
// create array
const shapes = ['triangle', 'square', 'triangle', 'circle', 'triangle'];
2. Second, apply the filter()
method in the array created in the previous step. Add the logic desired to filter elements of the original array. In this case, we are going to get only elements with the text equal to “triangle”.
// filter array to keep only "triangle"s
shapes.filter(function (element, index, array) {
return (element === 'triangle');
})
3. Assign a variable the filtered array result.
// assign filtered array value to the triangles.
const triangles = shapes.filter(function (element, index, array) {
return (element === 'triangle');
})
Defining a Callback Function without Optional Paramaters
In the previous example, we had defined a callback function with its three parameters.
// filter array to keep only "triangle"s
shapes.filter(function (element, index, array) {
return (element === 'triangle');
})
However, we didn’t use the index
and array
parameters in the callback function. We can rewrite the callback function without those two parameters and it will still work.
shapes.filter(function (element) {
return (element === 'triangle');
})
Defining a Callback Function using index
parameter
Let’s say we want to get only a certain number of elements from the original array instead of filtering by triangles. We can use the index
parameter of the callback function to get the top 3 elements of the original array.
shapes.filter(function (element, index) {
return (index <= 2);
});
Remember, the index number in an array starts with 0
for the first element of the array. Hence, if we want to get the top three elements of an array, the index of the third element in an array will be 2
.
Defining a Callback Function using array
parameter
If you have the original array assigned to a variable, there wouldn’t be any need to use the array
third argument.
const shapes = ['triangle', 'square', 'triangle', 'circle', 'triangle'];
shapes.filter(function (element) {
// log original array
console.log('original array ', shapes);
return (element === 'triangle');
})
You can also apply the filter()
method without necessarily assigning a variable to the original array.
['triangle', 'square', 'triangle', 'circle', 'triangle'].filter(
function (element) {
return (element === 'triangle');
}
);
In this case, there is no variable assigned to the array if we want to use the original array for additional logic inside the callback function. This is when it becomes handy to use the array
third parameter to have access to that original array becomes handy
['triangle', 'square', 'triangle', 'circle', 'triangle'].filter(
function (element, index, array) {
console.log('original array ', array); // it should log ['triangle', 'square', 'triangle', 'circle', 'triangle']
return (element === 'triangle');
}
);
Assigning a Variable to a Filter Callback Function
Another possibility is to define the callback function inside a variable and pass that variable as a parameter when calling the filter()
method. This allows reusing a callback function as we don’t always know the array using the filter()
method.
const filterTriangles = function (element, index, array) {
console.log('original array ', array); // it should log original array
return (element === 'triangle');
};
const firstArray = ['circle', 'square', 'triangle'];
const secondArray = ['triangle', 'triangle', 'circle'];
firstArray.filter(filterTriangles);
// it should log 3 times "original array ['circle', 'square', 'triangle']"
secondArray.filter(filterTriangles);
// it should log 3 times "original array ['triangle', 'triangle', 'circle']"
In these examples, we are not really using the array
third argument besides logging the original array, which it isn’t part of the logic determining what filtered values to get. We can say 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 in filter the elements based on the index value.
const getHalfArray = function (element, index, array) {
const half = Math.floor(array.length / 2);
return (index < half);
};
const shapes = ['circle', 'square', 'triangle', 'cylinder', 'cube', 'cone'];
const halfArray = shapes.filter(getHalfArray);
// halfArray should be ['circle', 'square', 'triangle'];
Using filter() Method Second Argument thisArg
It is not common to use thisArg
, second and optional argument when working with the filter()
method. To refresh your memory, you can use the filter()
method in two possible ways: without the thisArg
and with the thisArg
.
filter(callbackFn)
filter(callbackFn, thisArg)
When using the thisArg
, what we are modifying is the value of the keyword this
inside the callback function (callbackFn
). For example, if you define thisArg
as a number, the value of this
inside the callback function will be the number.
[-2,-1, 0, 1, 2].filter(function(element) {
// 'this' is equal to 0
return element > this;
}, 0);
// expected result
// [1, 2];
The value of thisArg
could be anything: a string, a number, an array, an object, etc. However, typically you assign the value of the owner object intending to reference. Let’s look at the following example:
var c = function() {
var prop = [1,2,3];
var add = function (number) {
this.prop.push(number);
}
var getTopThree = function () {
var limit = 3;
return this.prop.filter(function(element,index) {
console.log(this);
return index < limit;
});
}
return {
prop,
add,
getTopThree
}
}
We have the variable c
with a value of a function that returns prop
, add
, and getTopThree
internal variables.
If you pay attention to the getTopThree
function, it logs the value of this
besides the filtering the values of prop
. The log doesn’t serve for any other purpose besides explaining the concept of using thisArg
when using the filter()
method.
var = function () {
var limit = 3;
return this.prop.filter(function(element,index) {
console.log(this);
return index < limit;
});
}
If you call the getTopThree()
in the console of your browser, you will notice it will log the Window
object.
It is the Window
object as this
refers to the global object when this
is not explicitly defined.
If provide this
keyword as the second argument of the filter()
method, we will see a different object logged in the browser.
var c = function() {
var prop = [1,2,3];
var add = function (number) {
this.prop.push(number);
}
var getTopThree = function () {
var limit = 3;
return this.prop.filter(function(element,index) {
console.log(this);
return index < limit;
}, this); // notice we are provide 'this' keyword as the second argument
// in this case, 'this' will have the owner object, which is the function
// containing props, add, and getTopThree variables
}
return {
prop,
add,
getTopThree
}
}
Notice how the this
keyword inside the callback function no longer represents the Window
object, but instead it represents the function that is assigned to the variable c
and has internal variables prop
, add
, and getTopThree
.
The reason is because we are defining the owner object we want to access inside the filter()
‘s callback function. Otherwise, this
inside the filter()
‘s callback function will be the global object.
How to Filter Numbers in an Array
Filtering numbers in an array could be as simple as using the Number.isFinite()
method to determine if an element is a number.
const random = ['hello', 2, 0, true, { brand: 'Toyota'' }, [], -3.45 ];
random.filter((element) {
// checks if current element is a number
return Number.isFinite(element);
});
// expected result
// [2, 0, -3.45 ];
It is possible to rewrite the filter callback function without explicitly defining a function.
// checks if current element is a number
random.filter(Number.isFinite);
Although this can be confusing at first, it works the same way when we define a filter callback function in an array.
const callbackFn = function (element, index, array) {};
random.filter(callbackFn);
Think of callbackFn
the same as Number.isFinite
.
Using Number.isFinite
is a good solution as long as you are not looking to filter strings that have a numerical value such as '1'
or '-4'
in the following example.
const anotherRandom = ['1', 'blue', 2, '-4', 0, true, -3.45 ];
anotherRandom.filter(Number.isFinite);
// expected result
// [2, 0, -3.45 ];
A better solution, in that case, is to attempt to convert the element into a number and check the converted value with Number.isFinite
const anotherRandom = ['1', 'blue', 2, '-4', 0, true, -3.45 ];
anotherRandom.filter(function (element) {
return Number.isFinite(parseFloat(element));
});
// expected result
// ['1', 2, '-4', 0, -3.45];
Filter an Array of Objects by Value
Filtering an array of objects based on the value of the properties or keys is a common task you will run into when working on projects. Luckily is not much different than working with other types of values as long as you define the property used to filter the array. For example, if we want to get only the cars made in the current year, you can access the property year
for each element and run the conditional logic.
const cars = [
{ brand: 'Toyota', model: 'Corolla', year: 2021 },
{ brand: 'Ford', model: 'Mustang', year: 2008 },
{ brand: 'Dodge', model: 'Challenger', year: 2012},
];
cars.filter(function (element) {
// element will be the object { brand: 'car brand', model: 'car model, year: 'car year' };
return element.year === new Date().getFullYear();
});
// expected result
// [{brand: 'Toyota', model: 'Corolla', year: 2021}];
At this point, everything looks good. However, we could make a minor modification in the name used for the first parameter to name it to something that represents better the elements of the array instead of calling it element
. We are going to rename the parameter element
as car
.
cars.filter(function (car) {
return car.year === new Date().getFullYear();
});
Conclusion
The array filter()
method is used to filter values of an array. It provides a quick way to define logic to generate a new array based on filtering criteria inside a callback function. Although it is possible to provide the thisArg
when using the filter()
method, it is rarely used unless it is required to access
Was this article helpful?
Let me know by sharing your comments here or on Twitter.