Метод filter JavaScript: мощный способ поиска в массивах

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • начинающие и средние разработчики на 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 прост и элегантен, но скрывает в себе мощные возможности. Базовая структура выглядит следующим образом:

JS
Скопировать код
const newArray = array.filter(callback(element[, index[, array]])[, thisArg])

Где:

  • array — исходный массив, к которому применяется метод
  • callback — функция, которая проверяет каждый элемент. Если она возвращает true, элемент включается в результирующий массив
  • element — текущий обрабатываемый элемент массива
  • index (опционально) — индекс текущего элемента
  • array (опционально) — ссылка на исходный массив
  • thisArg (опционально) — значение, используемое в качестве this при выполнении callback

Функция обратного вызова (callback) должна возвращать булево значение (true/false) или значение, которое будет приведено к булевому. Если функция возвращает true, соответствующий элемент включается в новый массив.

Рассмотрим простой пример — фильтрация чисел больше 10 из массива:

JS
Скопировать код
const numbers = [5, 12, 8, 130, 44];
const filtered = numbers.filter(number => number > 10);
console.log(filtered); // [12, 130, 44]

А вот более практичный пример с массивом объектов:

JS
Скопировать код
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. Фильтрация по простому условию

JS
Скопировать код
// Фильтрация положительных чисел
const numbers = [-3, 5, 1, -4, 0, 8, -2];
const positiveNumbers = numbers.filter(num => num > 0);
console.log(positiveNumbers); // [5, 1, 8]

2. Фильтрация строк

JS
Скопировать код
// Поиск слов, содержащих определённую подстроку
const fruits = ['яблоко', 'банан', 'апельсин', 'мандарин', 'ананас'];
const aFruits = fruits.filter(fruit => fruit.includes('ан'));
console.log(aFruits); // ['банан', 'мандарин', 'ананас']

// Фильтрация строк по длине
const longFruits = fruits.filter(fruit => fruit.length > 6);
console.log(longFruits); // ['апельсин', 'мандарин']

3. Работа с массивом объектов

JS
Скопировать код
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. Фильтрация с несколькими условиями

JS
Скопировать код
// Найдем совершеннолетних пользователей, не являющихся админами
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. Фильтрация с использованием индекса элемента

JS
Скопировать код
// Получим только элементы с четными индексами
const evenIndexed = users.filter((user, index) => index % 2 === 0);
console.log(evenIndexed); // Алексей, Михаил (индексы 0, 2)

6. Удаление дубликатов из массива

JS
Скопировать код
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, можно разбить логику на несколько последовательных вызовов:

JS
Скопировать код
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. Динамические фильтры с замыканиями

Создание функций-генераторов фильтров позволяет многократно использовать логику фильтрации:

JS
Скопировать код
// Функция-генератор фильтров по сумме
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 можно применять для работы со сложными вложенными данными:

JS
Скопировать код
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 с регулярными выражениями

JS
Скопировать код
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. Фильтрация с использованием внешних данных

JS
Скопировать код
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 — только первое совпадение.

JS
Скопировать код
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 проверяют условия, но возвращают булево значение, а не массив.

JS
Скопировать код
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:

JS
Скопировать код
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 отбирает элементы. Часто их используют вместе:

JS
Скопировать код
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 более декларативен и лаконичен:

JS
Скопировать код
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. Комбинируйте эти методы, чтобы сделать ваш код максимально элегантным и эффективным. Помните: правильно выбранный инструмент — уже половина успеха в решении задачи.

Читайте также

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Что делает метод filter в JavaScript?
1 / 5

Загрузка...