Метод filter в JavaScript: как отфильтровать массив по условию

Чтобы отфильтровать массив в JavaScript, вызовите filter() с функцией-условием: метод вернёт новый массив из подходящих элементов, а исходный не изменится.

В статье шесть задач с кодом, от массива объектов до фильтра объекта, и пять ошибок, из-за которых filter выдаёт не тот результат.

Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 3267 статей автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3921 экспертное мнение Подписаться на Телеграм-канал
Обложка: Метод filter в JavaScript: как отфильтровать массив по условию

Чтобы отфильтровать массив в JavaScript, вызовите у него filter() и передайте функцию-условие: arr.filter(item => item > 10). Метод проверит каждый элемент и вернёт новый массив из тех, для которых функция вернула истинное значение. Исходный массив не меняется.

Ниже разберём синтаксис, шесть типовых задач с кодом и пять ошибок, из-за которых filter в JS выдаёт не тот результат. Если вы ещё путаетесь в самих массивах, начните с материала что такое массив и чем он отличается от списка.

Как работает filter в JavaScript

Рой сортирует карточки с данными через воронку-фильтр

Синтаксис короткий:

const result = array.filter((element, index, array) => {
  return условие;
}, thisArg);

Функция-условие получает три аргумента, нужен обычно только первый:

  • element: текущий элемент;
  • index: его номер в массиве;
  • array: сам массив, по которому идёт перебор.

Второй параметр thisArg задаёт this внутри функции. Со стрелочными функциями он не работает, поэтому в коде со стрелками его не передают.

Что возвращает filter: всегда новый массив. Если не подошёл ни один элемент, вернётся пустой [], так сказано в справочнике MDN по Array.prototype.filter(). Проверять результат на null не нужно.

const prices = [450, 1200, 89, 3000, 760];
const cheap = prices.filter(price => price < 1000);
console.log(cheap);
console.log(prices);

// [ 450, 89, 760 ]
// [ 450, 1200, 89, 3000, 760 ]

Как отфильтровать массив: пошаговая инструкция

Рой уверенно обходит грабли с чек-листом в лапе
  1. Определите, что оставить. Сформулируйте условие словами: «курсы дешевле 30 000», «активные пользователи», «строки, где есть слово».
  2. Запишите условие функцией, которая возвращает true или false: course => course.price < 30000.
  3. Вызовите filter у массива и передайте эту функцию.
  4. Сохраните результат в новую переменную. Метод не трогает исходный массив, поэтому без присваивания отфильтрованные данные потеряются.
  5. Проверьте, не пустой ли результат: if (result.length === 0). Пустой массив в условии if (result) всё равно считается истинным.

Как добавлять элементы в массив, рассказали в соседней инструкции как добавить объект в массив через push и spread.

Канал основателя Checkroi Вани Буявца3 800 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединиться

Примеры: шесть задач, которые решает filter

Сито отбирает нужные элементы из массива

Массив объектов по значению свойства

Типовая задача: из списка товаров, курсов или пользователей оставить подходящие по одному полю.

const courses = [
  { title: 'JavaScript с нуля', price: 0, level: 'junior' },
  { title: 'React для практиков', price: 42000, level: 'middle' },
  { title: 'Вёрстка за выходные', price: 0, level: 'junior' },
  { title: 'Node.js и базы данных', price: 56000, level: 'middle' },
];
const free = courses.filter(course => course.price === 0);
console.log(free.map(course => course.title));

// [ 'JavaScript с нуля', 'Вёрстка за выходные' ]

Несколько условий сразу

Условия соединяются через && (оба должны выполниться) или || (хватит одного). Отдельный filter на каждое условие писать не нужно.

const freeJunior = courses.filter(c => c.price === 0 && c.level === 'junior');
console.log(freeJunior.length);

// 2

Поиск по подстроке без учёта регистра

Так работает живой поиск по списку на сайте: пользователь вводит букву, список сжимается. Для фронтенда это рядовая задача, с чего начинать путь в профессию, описано в плане как стать фронтенд-разработчиком.

const cities = ['Москва', 'Казань', 'Мурманск', 'Самара'];
const query = 'м';
const found = cities.filter(city => city.toLowerCase().includes(query.toLowerCase()));
console.log(found);

// [ 'Москва', 'Мурманск', 'Самара' ]

Обе части приводим к нижнему регистру, иначе «Москва» не найдётся по строчной «м». В React списки фильтруют точно так же, только результат сразу уходит в разметку, а программы по этой библиотеке собраны в подборке курсов по React.

CheckroiCheckroiПодборка курсов по React.js68 курсов • 21 школаСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

Удалить дубликаты из массива

Здесь пригодится второй аргумент, индекс. Элемент остаётся, если его первое вхождение совпадает с текущей позицией.

const tags = ['js', 'css', 'js', 'html', 'css'];
const unique = tags.filter((tag, index, arr) => arr.indexOf(tag) === index);
console.log(unique);

// [ 'js', 'css', 'html' ]

На массиве из десятков тысяч элементов приём медленный: indexOf каждый раз проходит массив с начала. Для больших объёмов быстрее [...new Set(tags)].

Убрать пустые значения

const values = [0, 5, '', 'текст', null, undefined, NaN, 12];
console.log(values.filter(Boolean));
console.log(values.filter(v => v !== null && v !== undefined && v !== ''));

// [ 5, 'текст', 12 ]
// [ 0, 5, 'текст', NaN, 12 ]

Короткая запись filter(Boolean) выкидывает всё ложноподобное, включая ноль. Если ноль для вас осмысленное значение (цена, остаток на складе), пишите условие явно, как во второй строке.

Как отфильтровать объект

У обычного объекта метода filter нет. Объект сначала превращают в массив пар через Object.entries(), фильтруют и собирают обратно через Object.fromEntries().

const salaries = { anna: 120000, oleg: 85000, ira: 150000 };
const high = Object.fromEntries(
  Object.entries(salaries).filter(([name, sum]) => sum > 100000)
);
console.log(high);

// { anna: 120000, ira: 150000 }
CheckroiCheckroiПодборка курсов по Javascript209 курсов • 37 школСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

filter, find, map и reduce: какой метод выбрать

Синтаксис у этих методов почти одинаковый, а отвечают они на разные вопросы. Перепутаете, и придётся дописывать лишние строки.

Задача Метод Что вернёт
Оставить все подходящие элементы filter() новый массив, возможно пустой
Найти один, первый подходящий find() элемент или undefined
Преобразовать каждый элемент map() массив той же длины
Свести массив к одному значению reduce() число, строку, объект
Проверить, есть ли хоть один подходящий some() true или false

Методы складываются в цепочку, и в браузере, и на сервере в коде Node.js-разработчика. Например, посчитаем сумму недорогих товаров:

const products = [
  { name: 'Ноутбук', price: 85000 },
  { name: 'Мышь', price: 1500 },
  { name: 'Монитор', price: 23000 },
];
const total = products
  .filter(p => p.price < 30000)
  .map(p => p.price)
  .reduce((sum, price) => sum + price, 0);
console.log(total);

// 24500

Если нужен один элемент, берите find(): он остановится на первом совпадении, а filter пройдёт массив до конца и вернёт массив, из которого элемент ещё придётся достать через [0]. Что ещё из языка нужно знать на старте, собрали в материале о профессии JavaScript-разработчика.

Частые ошибки и что с ними делать

Фигурные скобки без return

Симптом: filter возвращает пустой массив, хотя подходящие элементы точно есть.

const nums = [1, 2, 3, 4];
const wrong = nums.filter(n => { n > 2 });
const right = nums.filter(n => { return n > 2; });
console.log(wrong, right);

// [] [ 3, 4 ]

Причина: стрелочная функция с фигурными скобками без return возвращает undefined, а это ложное значение.

Решение: уберите скобки (n => n > 2) или допишите return.

Изменили отфильтрованный объект, а поменялся исходный

const users = [{ name: 'Аня', active: true }, { name: 'Олег', active: false }];
const active = users.filter(u => u.active);
active[0].name = 'Анна';
console.log(users[0].name);

// Анна

Массив новый, но объекты внутри те же самые: метод копирует только ссылки на них. Если результат будете менять, скопируйте объекты: .map(u => ({ ...u })).

Асинхронная функция внутри filter

const ids = [1, 2, 3, 4];
const isEven = async id => id % 2 === 0;
console.log(ids.filter(isEven));

// [ 1, 2, 3, 4 ]

Async-функция возвращает промис, а промис всегда истинный, поэтому проходят все элементы. Сначала дождитесь проверок через Promise.all, потом фильтруйте по готовым результатам. Код ниже работает внутри async-функции или в модуле:

const checks = await Promise.all(ids.map(isEven));
const good = ids.filter((id, i) => checks[i]);

// [ 2, 4 ]

Ситуация типична для данных с сервера: как получать их запросом, рассказали в инструкции по fetch в JavaScript.

filter is not a function у элементов страницы

document.querySelectorAll() возвращает NodeList, коллекцию, похожую на массив. У неё есть forEach, но нет filter. Превратите коллекцию в массив: Array.from(document.querySelectorAll('li')).filter(...). Откуда берутся такие коллекции, объясняет разбор DOM-дерева в JavaScript.

Тип результата в TypeScript не сузился

Отфильтровали null, а TypeScript всё равно считает, что в массиве может быть null. Простые проверки вроде x => x !== null компилятор распознаёт сам начиная с версии 5.5: в анонсе TypeScript 5.5 это названо inferred type predicates. В старых версиях и при сложном условии подскажите тип явно функцией-предикатом: arr.filter((x): x is string => x !== null). Как работают такие проверки типов, описано в документации TypeScript о сужении типов, а с самим языком знакомит наш материал TypeScript: что это и как начать.

CheckroiCheckroiПодборка курсов по TypeScript59 курсов • 19 школСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

Где освоить JavaScript системно

filter решает одну задачу. Чтобы писать интерфейсы, нужны ещё асинхронность, DOM и TypeScript, и учить их проще на задачах, которые кто-то проверяет. Ниже пять программ из каталога курсов по JavaScript с ценой и длительностью.

КурсШколаСтоимость со скидкойВ рассрочкуДлитель­ностьОбзор курса от Checkroi
JavaScript
Перейти на сайт курса
SkillboxSkillbox63 876 ₽4086 ₽/мес.3 месяцаОбзор курса
Fullstack разработчик JavaScript
Перейти на сайт курса
OTUSOTUS75 000 ₽20 000 ₽/мес.6 месяцевОбзор курса
Факультет fullstack JavaScript
Перейти на сайт курса
GeekBrainsGeekBrains134 700 ₽3742 ₽/мес.15 месяцевОбзор курса
Fullstack-разработчик на JavaScript
Перейти на сайт курса
Академия ЭдюсонЭдюсон119 070 ₽4961 ₽/мес.11 месяцевОбзор курса
Фулстек-разработчик на JavaScript
Перейти на сайт курса
SkillboxSkillbox153 461 ₽4296 ₽/мес.11 месяцевОбзор курса

Больше программ — в полном каталоге курсов по Javascript

Часто задаваемые вопросы

Что возвращает filter в JS?

Новый массив из элементов, для которых функция-условие вернула истинное значение. Если не подошёл ни один элемент, вернётся пустой массив [].

Изменяет ли filter исходный массив?

Нет, исходный массив остаётся прежним. Но объекты внутри результата общие с исходным массивом: метод копирует ссылки, поэтому правка объекта в новом массиве видна и в старом.

Чем filter отличается от find?

find возвращает первый подходящий элемент или undefined и останавливается на нём. filter проходит весь массив и всегда возвращает массив, даже если подошёл один элемент.

Как отфильтровать массив объектов по свойству?

Обратитесь к свойству внутри функции-условия: users.filter(user => user.active) оставит активных пользователей. Несколько условий соединяйте через && или ||.

Почему filter возвращает пустой массив?

Проверьте, возвращает ли функция значение. Стрелочная функция с фигурными скобками без return отдаёт undefined, и ни один элемент не проходит. Уберите скобки или допишите return.

Можно ли применить filter к объекту?

Напрямую нет, у объекта такого метода нет. Превратите объект в массив пар через Object.entries(), отфильтруйте и соберите обратно через Object.fromEntries().

Читайте Checkroi первым в Google
Добавьте Checkroi в избранные источники — и наши разборы курсов и обзоры школ будут показываться выше в вашей выдаче Google.
Оставить комментарий
0 комментариев
Форма комментария

Оставьте комментарий

Напишите, что думаете. Нам важно ваше мнение!