Метод filter JavaScript: мощный способ поиска в массивах
Для кого эта статья:
- начинающие и средние разработчики на JavaScript
- студенты, обучающиеся веб-разработке
профессионалы, стремящиеся улучшить свои навыки работы с массивами и методами JavaScript
Метод
filter— один из наиболее мощных инструментов JavaScript для манипуляции с массивами. С его помощью разработчик может быстро извлечь подмножество элементов, удовлетворяющих определенному условию, не прибегая к мучительным циклам и временным массивам. Владение этим методом критически важно для эффективного кодирования — оно позволяет писать элегантный, производительный и легко читаемый код. 🔍 Когда я впервые освоилfilter, скорость моей работы с данными увеличилась в разы.
Хотите быстро овладеть не только методом
filter, но и другими мощными приемами JavaScript? Обучение веб-разработке от Skypro — это глубокое погружение в реальное программирование с первых же занятий. Вы не просто изучите теорию массивов и их методов, а будете сразу применятьfilter,mapиreduceв живых проектах под руководством практикующих разработчиков. Ваш код станет чище, быстрее и профессиональнее!
Что такое метод filter и его роль в работе с массивами
Метод filter — это встроенный метод массивов в JavaScript, который создаёт новый массив, содержащий только те элементы исходного массива, которые прошли проверку, заданную в передаваемой функции. Этот метод не изменяет исходный массив — важное преимущество, соответствующее принципам функционального программирования.
Проще говоря, filter просеивает массив, оставляя только те элементы, которые соответствуют вашим критериям. Представьте, что у вас есть сито для муки — метод filter работает аналогично, пропуская через себя только "правильные" элементы.
Алексей Петров, Senior Frontend Developer
Однажды я работал над проектом с огромным массивом транзакций — более 50 000 записей. Каждая содержала информацию о покупателе, товаре, дате и сумме. Мне нужно было быстро найти все транзакции определённого клиента за конкретный месяц.
Сначала я написал вложенные циклы с условиями, и страница начала ощутимо тормозить. Переписав логику на один элегантный вызов
filter, я не только сократил код с 30 строк до 3, но и получил прирост производительности — страница стала загружаться в 5 раз быстрее. Это был момент, когда я по-настоящему оценил силу функциональных методов JavaScript.
Метод filter особенно ценен, когда вы работаете с массивами объектов и вам нужно отфильтровать их по определенным свойствам. Например, найти все товары дороже 1000 рублей, все записи за текущий месяц или все задачи с высоким приоритетом.
Вот ключевые преимущества использования метода filter:
- Иммутабельность — исходный массив остаётся неизменным
- Декларативность — вы описываете что хотите получить, а не как это сделать
- Лаконичность — меньше кода, меньше ошибок
- Читаемость — код становится более понятным
- Комбинируемость — можно легко соединять с другими методами массивов
| Ситуация | Традиционный подход | Решение с filter |
|---|---|---|
| Найти все чётные числа | Цикл for с проверкой условия и push в новый массив | numbers.filter(num => num % 2 === 0) |
| Найти продукты в наличии | Цикл forEach с условием и добавлением в результат | products.filter(product => product.inStock) |
| Фильтр по нескольким условиям | Вложенные if-условия внутри цикла | users.filter(user => user.age > 18 && user.isActive) |

Синтаксис метода filter для поиска элементов в массиве
Синтаксис метода filter прост и элегантен, но скрывает в себе мощные возможности. Базовая структура выглядит следующим образом:
const newArray = array.filter(callback(element[, index[, array]])[, thisArg])
Где:
- array — исходный массив, к которому применяется метод
- callback — функция, которая проверяет каждый элемент. Если она возвращает true, элемент включается в результирующий массив
- element — текущий обрабатываемый элемент массива
- index (опционально) — индекс текущего элемента
- array (опционально) — ссылка на исходный массив
- thisArg (опционально) — значение, используемое в качестве this при выполнении callback
Функция обратного вызова (callback) должна возвращать булево значение (true/false) или значение, которое будет приведено к булевому. Если функция возвращает true, соответствующий элемент включается в новый массив.
Рассмотрим простой пример — фильтрация чисел больше 10 из массива:
const numbers = [5, 12, 8, 130, 44];
const filtered = numbers.filter(number => number > 10);
console.log(filtered); // [12, 130, 44]
А вот более практичный пример с массивом объектов:
const products = [
{ name: 'Ноутбук', price: 45000, available: true },
{ name: 'Смартфон', price: 25000, available: false },
{ name: 'Наушники', price: 5000, available: true },
{ name: 'Монитор', price: 15000, available: true }
];
// Найдем доступные товары дешевле 20000
const affordableProducts = products.filter(product =>
product.available && product.price < 20000
);
console.log(affordableProducts);
// [
// { name: 'Наушники', price: 5000, available: true },
// { name: 'Монитор', price: 15000, available: true }
// ]
Обратите внимание на то, что filter всегда возвращает массив. Даже если условию удовлетворяет только один элемент, результатом будет массив с одним элементом. Если ни один элемент не удовлетворяет условию, возвращается пустой массив.
Базовые сценарии фильтрации данных с кодом
Давайте рассмотрим несколько типичных сценариев использования метода filter для поиска в массиве. Эти примеры охватывают большинство распространённых задач, с которыми сталкиваются разработчики. 🔎
1. Фильтрация по простому условию
// Фильтрация положительных чисел
const numbers = [-3, 5, 1, -4, 0, 8, -2];
const positiveNumbers = numbers.filter(num => num > 0);
console.log(positiveNumbers); // [5, 1, 8]
2. Фильтрация строк
// Поиск слов, содержащих определённую подстроку
const fruits = ['яблоко', 'банан', 'апельсин', 'мандарин', 'ананас'];
const aFruits = fruits.filter(fruit => fruit.includes('ан'));
console.log(aFruits); // ['банан', 'мандарин', 'ананас']
// Фильтрация строк по длине
const longFruits = fruits.filter(fruit => fruit.length > 6);
console.log(longFruits); // ['апельсин', 'мандарин']
3. Работа с массивом объектов
const users = [
{ id: 1, name: 'Алексей', age: 25, isAdmin: false },
{ id: 2, name: 'Елена', age: 31, isAdmin: true },
{ id: 3, name: 'Михаил', age: 17, isAdmin: false },
{ id: 4, name: 'Ольга', age: 28, isAdmin: true }
];
// Фильтрация совершеннолетних пользователей
const adults = users.filter(user => user.age >= 18);
console.log(adults); // все кроме Михаила
// Поиск администраторов
const admins = users.filter(user => user.isAdmin);
console.log(admins); // Елена и Ольга
4. Фильтрация с несколькими условиями
// Найдем совершеннолетних пользователей, не являющихся админами
const regularAdults = users.filter(user => user.age >= 18 && !user.isAdmin);
console.log(regularAdults); // только Алексей
// С использованием ИЛИ (OR)
const specialUsers = users.filter(user => user.isAdmin || user.age < 18);
console.log(specialUsers); // Елена, Михаил, Ольга
5. Фильтрация с использованием индекса элемента
// Получим только элементы с четными индексами
const evenIndexed = users.filter((user, index) => index % 2 === 0);
console.log(evenIndexed); // Алексей, Михаил (индексы 0, 2)
6. Удаление дубликатов из массива
const numbers = [1, 2, 2, 3, 4, 4, 5];
const unique = numbers.filter((value, index, self) =>
self.indexOf(value) === index
);
console.log(unique); // [1, 2, 3, 4, 5]
Мария Соколова, Lead JavaScript Developer
В проекте e-commerce системы мне пришлось реализовать многоуровневую фильтрацию товаров. Пользователи могли фильтровать по цене, категориям, рейтингу, наличию и десяткам других параметров.
Изначально у нас был монструозный код с множеством условных операторов и вложенных циклов. После рефакторинга мы пришли к элегантному решению с использованием замыканий и метода
filter:JSСкопировать кодfunction createProductFilter() { const filters = []; return { addFilter(filterFn) { filters.push(filterFn); return this; }, execute(products) { return products.filter(product => filters.every(filter => filter(product)) ); } }; } // Использование const filter = createProductFilter(); filter .addFilter(p => p.price >= 1000) .addFilter(p => p.rating > 4) .addFilter(p => p.inStock); const filteredProducts = filter.execute(allProducts);Этот подход не только сделал код более читаемым и поддерживаемым, но и позволил легко добавлять новые фильтры без изменения существующего кода.
Продвинутые техники применения filter в JavaScript
После освоения базовых сценариев использования метода filter для поиска в массиве, давайте перейдем к более сложным и мощным техникам. Эти приемы демонстрируют истинный потенциал метода filter и могут значительно улучшить ваш код. 🚀
1. Композиция фильтров
Вместо создания сложных условий в одном filter, можно разбить логику на несколько последовательных вызовов:
const transactions = [
{ id: 1, amount: 500, type: 'debit', category: 'groceries' },
{ id: 2, amount: 1500, type: 'credit', category: 'salary' },
{ id: 3, amount: 200, type: 'debit', category: 'entertainment' },
{ id: 4, amount: 800, type: 'debit', category: 'groceries' }
];
// Последовательная фильтрация
const expensiveDebits = transactions
.filter(t => t.type === 'debit')
.filter(t => t.amount > 300)
.filter(t => t.category === 'groceries');
console.log(expensiveDebits);
// [{ id: 1, amount: 500, type: 'debit', category: 'groceries' },
// { id: 4, amount: 800, type: 'debit', category: 'groceries' }]
2. Динамические фильтры с замыканиями
Создание функций-генераторов фильтров позволяет многократно использовать логику фильтрации:
// Функция-генератор фильтров по сумме
function createAmountFilter(min, max) {
return transaction => transaction.amount >= min && transaction.amount <= max;
}
// Функция-генератор фильтров по типу
function createTypeFilter(type) {
return transaction => transaction.type === type;
}
// Использование
const mediumAmountFilter = createAmountFilter(300, 700);
const debitFilter = createTypeFilter('debit');
const mediumDebits = transactions
.filter(debitFilter)
.filter(mediumAmountFilter);
console.log(mediumDebits);
// [{ id: 1, amount: 500, type: 'debit', category: 'groceries' }]
3. Фильтрация вложенных структур
Метод filter можно применять для работы со сложными вложенными данными:
const departments = [
{
name: 'Engineering',
employees: [
{ name: 'Alice', salary: 100000 },
{ name: 'Bob', salary: 90000 }
]
},
{
name: 'Marketing',
employees: [
{ name: 'Charlie', salary: 80000 },
{ name: 'Dave', salary: 85000 }
]
}
];
// Найдём отделы с высокооплачиваемыми сотрудниками
const highPayingDepts = departments.filter(dept =>
dept.employees.some(emp => emp.salary > 95000)
);
console.log(highPayingDepts);
// [{ name: 'Engineering', employees: [...] }]
4. Использование filter с регулярными выражениями
const messages = [
'Привет, как дела?',
'Мой номер: +7 (123) 456-78-90',
'Встретимся в 15:30',
'Контакт: mail@example.com'
];
// Найдём сообщения, содержащие email
const emailRegex = /\S+@\S+\.\S+/;
const emailMessages = messages.filter(msg => emailRegex.test(msg));
console.log(emailMessages);
// ['Контакт: mail@example.com']
// Найдём сообщения, содержащие телефонные номера
const phoneRegex = /\+\d[\d\s\(\)-]{10,}/;
const phoneMessages = messages.filter(msg => phoneRegex.test(msg));
console.log(phoneMessages);
// ['Мой номер: +7 (123) 456-78-90']
5. Фильтрация с использованием внешних данных
const products = [
{ id: 1, name: 'Ноутбук', categoryId: 1 },
{ id: 2, name: 'Смартфон', categoryId: 2 },
{ id: 3, name: 'Планшет', categoryId: 2 },
{ id: 4, name: 'Мышь', categoryId: 3 }
];
const allowedCategories = [1, 3];
// Фильтруем товары по разрешенным категориям
const allowedProducts = products.filter(product =>
allowedCategories.includes(product.categoryId)
);
console.log(allowedProducts);
// [{ id: 1, name: 'Ноутбук', categoryId: 1 },
// { id: 4, name: 'Мышь', categoryId: 3 }]
| Техника | Преимущества | Недостатки | Когда использовать |
|---|---|---|---|
| Композиция фильтров | Чистый, читаемый код, легко модифицировать | Многократное прохождение по массиву | Когда требуется множество условий фильтрации |
| Динамические фильтры | Переиспользуемость, гибкость | Повышенная сложность кода | Когда нужно повторно использовать фильтры |
| Регулярные выражения | Мощные возможности поиска по шаблону | Сложность написания и отладки регулярок | Для текстовых данных с определённой структурой |
| Фильтрация вложенных структур | Работает с комплексными данными | Может быть медленнее для глубоких структур | Для сложных иерархических данных |
Сравнение filter с другими методами поиска в массивах
Метод filter для поиска в массиве — не единственный инструмент в вашем арсенале. JavaScript предоставляет несколько других методов для поиска и отбора элементов, каждый со своими сильными сторонами. Чтобы выбрать правильный метод, важно понимать различия между ними. 🧐
1. filter vs find
Основное различие: filter возвращает массив всех совпадающих элементов, find — только первое совпадение.
const numbers = [5, 12, 8, 130, 44];
// filter возвращает массив всех совпадений
const allLargeNumbers = numbers.filter(num => num > 10);
console.log(allLargeNumbers); // [12, 130, 44]
// find возвращает только первое совпадение
const firstLargeNumber = numbers.find(num => num > 10);
console.log(firstLargeNumber); // 12
Используйте filter, когда нужны все элементы, удовлетворяющие условию. Используйте find, когда достаточно найти первый подходящий элемент.
2. filter vs some/every
some и every проверяют условия, но возвращают булево значение, а не массив.
const numbers = [5, 12, 8, 130, 44];
// filter находит элементы, удовлетворяющие условию
const largeNumbers = numbers.filter(num => num > 10);
console.log(largeNumbers); // [12, 130, 44]
// some проверяет, есть ли хотя бы один элемент, удовлетворяющий условию
const hasLargeNumbers = numbers.some(num => num > 10);
console.log(hasLargeNumbers); // true
// every проверяет, удовлетворяют ли все элементы условию
const allLargeNumbers = numbers.every(num => num > 10);
console.log(allLargeNumbers); // false
Используйте some, когда нужно только проверить наличие элементов, соответствующих условию. Используйте every, когда нужно убедиться, что все элементы соответствуют условию.
3. filter vs reduce
reduce более универсален, но сложнее в использовании. С его помощью можно реализовать функциональность filter:
const numbers = [5, 12, 8, 130, 44];
// Стандартный filter
const filteredWithFilter = numbers.filter(num => num > 10);
// Та же задача с reduce
const filteredWithReduce = numbers.reduce((result, num) => {
if (num > 10) {
result.push(num);
}
return result;
}, []);
console.log(filteredWithFilter); // [12, 130, 44]
console.log(filteredWithReduce); // [12, 130, 44]
Используйте reduce для более сложной логики, когда требуется одновременно фильтровать и преобразовывать данные.
4. filter vs map
map преобразует каждый элемент, filter отбирает элементы. Часто их используют вместе:
const products = [
{ id: 1, name: 'Ноутбук', price: 45000, available: true },
{ id: 2, name: 'Смартфон', price: 25000, available: false },
{ id: 3, name: 'Наушники', price: 5000, available: true }
];
// Только filter: получаем доступные продукты
const availableProducts = products.filter(product => product.available);
console.log(availableProducts); // [{id: 1, ...}, {id: 3, ...}]
// Только map: преобразуем формат всех продуктов
const productsInfo = products.map(product => ({
title: product.name,
cost: product.price
}));
console.log(productsInfo); // [{title: 'Ноутбук', cost: 45000}, ...]
// Цепочка filter + map: отбираем и преобразуем
const availableInfo = products
.filter(product => product.available)
.map(product => ({ title: product.name, cost: product.price }));
console.log(availableInfo); // [{title: 'Ноутбук', cost: 45000}, {title: 'Наушники', cost: 5000}]
5. filter vs for-цикл
Традиционный цикл for даёт больше контроля, но filter более декларативен и лаконичен:
const numbers = [5, 12, 8, 130, 44];
// filter
const largeNumbers = numbers.filter(num => num > 10);
// Эквивалент с циклом for
const largeNumbersFor = [];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] > 10) {
largeNumbersFor.push(numbers[i]);
}
}
console.log(largeNumbers); // [12, 130, 44]
console.log(largeNumbersFor); // [12, 130, 44]
- Используйте
filterдля более чистого, функционального кода - Используйте
for, когда требуется больше контроля (например, раннее прерывание цикла)
Сводная таблица методов поиска в массивах:
| Метод | Возвращаемое значение | Назначение | Когда использовать |
|---|---|---|---|
filter() | Новый массив с подходящими элементами | Отбор нескольких элементов | Когда нужны все элементы, соответствующие условию |
find() | Первый подходящий элемент или undefined | Поиск одного элемента | Когда нужен только первый элемент, соответствующий условию |
some() | true/false | Проверка наличия элементов | Когда нужно только узнать, есть ли подходящие элементы |
every() | true/false | Проверка всех элементов | Когда нужно убедиться, что все элементы соответствуют условию |
reduce() | Любой тип данных | Универсальная обработка массива | Для сложных операций и комбинирования разных типов обработки |
Метод
filter— это мощный инструмент в наборе каждого JavaScript-разработчика. Понимание того, как и когда его применять, значительно улучшает качество вашего кода и делает его более читаемым и поддерживаемым. Однако не стоит забывать, чтоfilter— часть большого семейства методов для работы с массивами. Настоящий профессионал знает, когда использоватьfilter, а когда лучше применитьfind,someилиreduce. Комбинируйте эти методы, чтобы сделать ваш код максимально элегантным и эффективным. Помните: правильно выбранный инструмент — уже половина успеха в решении задачи.
Читайте также
- Зарплата data scientist и аналитика данных в Москве
- Группировка и агрегация в pandas: превращение хаоса в инсайты
- Средняя зарплата data scientist
- Обучение нейронных сетей на Python: пошаговое руководство
- Полиномиальная регрессия: моделирование нелинейных данных в Python
- Jupyter Notebook и Google Colab: сравнение интерактивных сред анализа
- Кросс-валидация в машинном обучении: защита от переобучения
- Компьютерное зрение Python: техники обработки изображений и детекции
- Анализ данных: как научиться работать с информацией и не утонуть
- Аналитика данных для бизнеса: как превратить цифры в прибыль