Метод filter()
создаёт новый массив со всеми элементами, прошедшими проверку, задаваемую в передаваемой функции.
Источник этого интерактивного примера хранится в репозитории GitHub. Если вы хотите внести свой вклад в проект интерактивных примеров, скопируйте https://github.com/mdn/interactive-examples и отправьте нам запрос на перенос.
Синтаксис
let newArray = arr.filter(callback(element[, index, [array]])[, thisArg])
Параметры
callback
- Функция, которая будет вызвана для каждого элемента массива. Если функция возвращает
true
, то элемент остаётся в массиве, еслиfalse
, то удаляется. - В функцию будет передано три аргумента:
-
element
- Текущий обрабатываемый элемент в массиве.
index
Необязательный- Индекс текущего обрабатываемого элемента в массиве.
array
Необязательный- Массив, по которому осуществляется проход.
thisArg
Необязательный- Значение, используемое в качестве
this
при вызове функцииcallback
.
Возвращаемое значение
Вернётся новый массив с элементами, которые проходят тест, то есть callback
вернёт true
. Если ни один элемент не пройдёт тест, то будет возвращён пустой массив.
Описание
Метод filter()
вызывает переданную функцию callback
один раз для каждого элемента, присутствующего в массиве, и конструирует новый массив со всеми значениями, для которых функция callback
вернула true
или значение, становящееся true при приведении в boolean. Функция callback
вызывается только для индексов массива, имеющих присвоенные значения; она не вызывается для индексов, которые были удалены или которым значения никогда не присваивались. Элементы массива, не прошедшие проверку функцией callback
, просто пропускаются и не включаются в новый массив.
Функция callback
вызывается с тремя аргументами:
- значение элемента;
- индекс элемента;
- массив, по которому осуществляется проход.
Если в метод filter()
был передан параметр thisArg
, при вызове callback
он будет использоваться в качестве значения this
. В противном случае, в качестве значения this
будет использоваться значение
. В конечном итоге, значение undefined
this
, наблюдаемое из функции callback
, определяется согласно обычным правилам определения
.this
, видимого из функции
Метод filter()
не изменяет массив, для которого он был вызван.
Диапазон элементов, обрабатываемых методом filter()
, устанавливается до первого вызова функции callback
. Элементы, добавленные в массив после начала выполнения метода filter()
, не будут посещены функцией callback
. Если существующие элементы массива изменятся, значения, переданные в функцию callback
, будут значениями на тот момент времени, когда метод filter()
посетит их; удалённые элементы посещены не будут.
Примеры
Отфильтровывание всех маленьких значений
Следующий пример использует filter()
для создания отфильтрованного массива, все элементы которого больше или равны 10, а все меньшие 10 удалены.
function isBigEnough(value) {
return value >= 10;
}
let filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// массив filtered равен [12, 130, 44]
Найти все простые числа в массиве
Следующий пример возвращает все простые числа в массиве:
let array = [4, 6, 8, 9, 12, 53, -17, 2, 5, 7, 31, 97, -1, 17];
function isPrime(num) {
if (num <= 1)
return false;
else if (num === 2)
return true;
else {
for (let i = 2; i < num; i++)
if (num % i === 0)
return false;
return true;
}
}
console.log(array.filter(isPrime)); // [53, 2, 5, 7, 31, 97, 17]
Фильтрация неверных записей в JSON
В следующем примере метод filter()
используется для создания отфильтрованного объекта JSON, все элементы которого содержат ненулевое числовое поле id
.
var arr = [
{ id: 15 },
{ id: -1 },
{ id: 0 },
{ id: 3 },
{ id: 12.2 },
{ },
{ id: null },
{ id: NaN },
{ id: 'undefined' }
];
var invalidEntries = 0;
function isNumber(obj) {
return obj!== undefined && typeof(obj) === 'number' && !isNaN(obj);
}
function filterByID(item) {
if (isNumber(item.id) && item.id !== 0) {
return true;
}
invalidEntries++;
return false;
}
var arrByID = arr.filter(filterByID);
console.log('Отфильтрованный массив\n', arrByID);
// Filtered Array
// [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]
console.log('Количество ошибочных записей = ', invalidEntries);
// Number of Invalid Entries = 5
Поиск в массиве
В следующем примере filter()
используется для фильтрации содержимого массива на основе входных данных.
var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
/**
* Элементы массива фильтруется на основе критериев поиска (query)
*/
function filterItems(query) {
return fruits.filter(function(el) {
return el.toLowerCase().indexOf(query.toLowerCase()) > -1;
})
}
console.log(filterItems('ap')); // ['apple', 'grapes']
console.log(filterItems('an')); // ['banana', 'mango', 'orange']
ES2015 реализация
const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
/**
* Элементы массива фильтруется на основе критериев поиска (query)
*/
const filterItems = (query) => {
return fruits.filter((el) =>
el.toLowerCase().indexOf(query.toLowerCase()) > -1
);
}
console.log(filterItems('ap')); // ['apple', 'grapes']
console.log(filterItems('an')); // ['banana', 'mango', 'orange']
Влияние на начальный массив (изменение, добавление и удаление)
В следующих примерах проверяется поведение метода filter
при изменении массива.
// Изменение всех элементов
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)
// Обратите внимание, что есть три слова длиной менее 6, но так как они были изменены,
// возвращается одно слово ['spray']
// Добавление новых элементов
words = ['spray', 'limit', 'exuberant', 'destruction','elite', 'present']
const appendedWords = words.filter( (word, index, arr) => {
arr.push('new')
return word.length < 6
})
console.log(appendedWords)
// Только три слова удовлетворяют условию, хотя `words` теперь имеет куда больше слов,
// длинной меньше 6 символов: ['spray', 'limit', 'elite']
// Удаление элементов
words = ['spray', 'limit', 'exuberant', 'destruction', 'elite', 'present']
const deleteWords = words.filter( (word, index, arr) => {
arr.pop()
return word.length < 6
})
console.log(deleteWords)
// Заметьте, что 'elite' не получено, так как удалено из `words` до того,
// как filter смог получить его: ['spray', 'limit']
Полифилл
Метод filter()
был добавлен к стандарту ECMA-262 в 5-м издании; поэтому он может отсутствовать в других реализациях стандарта. Вы можете работать с ним, добавив следующий код в начало ваших скриптов, он позволяет использовать filter()
в реализациях, которые не поддерживают этот метод. Этот алгоритм является точно тем, что описан в ECMA-262 5-го издания; он предполагает, что fn.call
вычисляется в оригинальное значение Function.prototype.call()
и что Array.prototype.push()
содержит своё оригинальное значение.
if (!Array.prototype.filter) {
Array.prototype.filter = function(fun/*, thisArg*/) {
'use strict';
if (this === void 0 || this === null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function') {
throw new TypeError();
}
var res = [];
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t) {
var val = t[i];
// ПРИМЕЧАНИЕ: Технически, здесь должен быть Object.defineProperty на
// следующий индекс, поскольку push может зависеть от
// свойств на Object.prototype и Array.prototype.
// Но этот метод новый и коллизии должны быть редкими,
// так что используем более совместимую альтернативу.
if (fun.call(thisArg, val, i, t)) {
res.push(val);
}
}
}
return res;
};
}
Спецификации
Спецификация | Статус | Комментарии |
---|---|---|
ECMAScript 5.1 (ECMA-262) Определение 'Array.prototype.filter' в этой спецификации. |
Стандарт | Изначальное определение. Реализована в JavaScript 1.6. |
ECMAScript 2015 (6th Edition, ECMA-262) Определение 'Array.prototype.filter' в этой спецификации. |
Стандарт | |
ECMAScript (ECMA-262) Определение 'Array.prototype.filter' в этой спецификации. |
Живой стандарт |
Совместимость с браузерами
BCD tables only load in the browser