The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Syntax
let newArray = arr.filter(callback(element[, index, [array]])[, thisArg])
Parameters
callback-
Function is a predicate, to test each element of the array. Return
trueto keep the element,falseotherwise.It accepts three arguments:
element- The current element being processed in the array.
indexOptional- The index of the current element being processed in the array.
arrayOptional- The array
filterwas called upon.
thisArgOptional- Value to use as
thiswhen executingcallback.
Return value
A new array with the elements that pass the test. If no elements pass the test, an empty array will be returned.
Description
filter() calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a value that coerces to true. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Array elements which do not pass the callback test are simply skipped, and are not included in the new array.
callback is invoked with three arguments:
- the value of the element
- the index of the element
- the Array object being traversed
If a thisArg parameter is provided to filter, it will be used as the callback's this value. Otherwise, the value undefined will be used as its this value. The this value ultimately observable by callback is determined according to the usual rules for determining the this seen by a function.
filter() does not mutate the array on which it is called.
The range of elements processed by filter() is set before the first invocation of callback. Elements which are appended to the array (from callback) after the call to filter() begins will not be visited by callback. If existing elements of the array are deleted in the same way they will not be visited.
Polyfill
filter() was added to the ECMA-262 standard in the 5th edition. Therefore, it may not be present in all implementations of the standard.
You can work around this by inserting the following code at the beginning of your scripts, allowing use of filter() in ECMA-262 implementations which do not natively support it. This algorithm is exactly equivalent to the one specified in ECMA-262, 5th edition, assuming that fn.call evaluates to the original value of Function.prototype.bind(), and that Array.prototype.push() has its original value.
if (!Array.prototype.filter){
Array.prototype.filter = function(func, thisArg) {
'use strict';
if ( ! ((typeof func === 'Function' || typeof func === 'function') && this) )
throw new TypeError();
var len = this.length >>> 0,
res = new Array(len), // preallocate array
t = this, c = 0, i = -1;
var kValue;
if (thisArg === undefined){
while (++i !== len){
// checks to see if the key was set
if (i in this){
kValue = t[i]; // in case t is changed in callback
if (func(t[i], i, t)){
res[c++] = kValue;
}
}
}
}
else{
while (++i !== len){
// checks to see if the key was set
if (i in this){
kValue = t[i];
if (func.call(thisArg, t[i], i, t)){
res[c++] = kValue;
}
}
}
}
res.length = c; // shrink down array to proper size
return res;
};
}
Examples
Filtering out all small values
The following example uses filter() to create a filtered array that has all elements with values less than 10 removed.
function isBigEnough(value) {
return value >= 10
}
let filtered = [12, 5, 8, 130, 44].filter(isBigEnough)
// filtered is [12, 130, 44]
Find all prime numbers in an array
The following example returns all prime numbers in the array:
const array = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
function isPrime(num) {
for (let i = 2; num > i; i++) {
if (num % i == 0) {
return false;
}
}
return num > 1;
}
console.log(array.filter(isPrime)); // [2, 3, 5, 7, 11, 13]
Filtering invalid entries from JSON
The following example uses filter() to create a filtered json of all elements with non-zero, numeric id.
let arr = [
{ id: 15 },
{ id: -1 },
{ id: 0 },
{ id: 3 },
{ id: 12.2 },
{ },
{ id: null },
{ id: NaN },
{ id: 'undefined' }
]
let invalidEntries = 0
function filterByID(item) {
if (Number.isFinite(item.id) && item.id !== 0) {
return true
}
invalidEntries++
return false;
}
let arrByID = arr.filter(filterByID)
console.log('Filtered Array\n', arrByID)
// Filtered Array
// [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]
console.log('Number of Invalid Entries = ', invalidEntries)
// Number of Invalid Entries = 5
Searching in array
Following example uses filter() to filter array content based on search criteria.
let fruits = ['apple', 'banana', 'grapes', 'mango', 'orange']
/**
* Filter array items based on search criteria (query)
*/
function filterItems(arr, query) {
return arr.filter(function(el) {
return el.toLowerCase().indexOf(query.toLowerCase()) !== -1
})
}
console.log(filterItems(fruits, 'ap')) // ['apple', 'grapes']
console.log(filterItems(fruits, 'an')) // ['banana', 'mango', 'orange']
ES2015 Implementation
const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange']
/**
* Filter array items based on search criteria (query)
*/
const filterItems = (arr, query) => {
return arr.filter(el => el.toLowerCase().indexOf(query.toLowerCase()) !== -1)
}
console.log(filterItems(fruits, 'ap')) // ['apple', 'grapes']
console.log(filterItems(fruits, 'an')) // ['banana', 'mango', 'orange']
Affecting Initial Array (modifying, appending and deleting)
The following examples tests the behavior of the filter method when the array is modified.
// Modifying each words
let words = ['spray', 'limit', 'exuberant', 'destruction','elite', 'present']
const modifiedWords = words.filter( (word, index, arr) => {
arr[index+1] +=' extra'
return word.length < 6
})
console.log(modifiedWords)
// Notice there are three words below length 6, but since they've been modified one is returned
// ["spray"]
// Appending new words
words = ['spray', 'limit', 'exuberant', 'destruction','elite', 'present']
const appendedWords = words.filter( (word, index, arr) => {
arr.push('new')
return word.length < 6
})
console.log(appendedWords)
// Only three fits the condition even though the `words` itself now has a lot more words with character length less than 6
// ["spray" ,"limit" ,"elite"]
// Deleting words
words = ['spray', 'limit', 'exuberant', 'destruction', 'elite', 'present']
const deleteWords = words.filter( (word, index, arr) => {
arr.pop()
return word.length < 6
})
console.log(deleteWords)
// Notice 'elite' is not even obtained as its been popped off `words` before filter can even get there
// ["spray" ,"limit"]
Specifications
| Specification |
|---|
| ECMAScript (ECMA-262) The definition of 'Array.prototype.filter' in that specification. |
Browser compatibility
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
filter | Chrome Full support 1 | Edge Full support 12 | Firefox Full support 1.5 | IE Full support 9 | Opera Full support 9.5 | Safari Full support 3 | WebView Android Full support ≤37 | Chrome Android Full support 18 | Firefox Android Full support 4 | Opera Android Full support 10.1 | Safari iOS Full support 1 | Samsung Internet Android Full support 1.0 | nodejs Full support 0.1.100 |
Legend
- Full support
- Full support
