Фильтрация массивов в JavaScript: все способы и практические примеры
Фильтрация массивов в JavaScript: методы и подходы
Фильтрация данных - одна из частых задач при работе с массивами. В JavaScript существует несколько способов отбора элементов, удовлетворяющих условию. Ниже рассмотрены основные варианты с примерами и разбором типичных ошибок.
Как отфильтровать массив по условию, используя стандартный метод Array.prototype.filter?
Метод filter() создаёт новый массив, содержащий все элементы исходного массива, для которых колбэк-функция возвращает true. Это наиболее эффективное и читаемое решение для большинства случаев.
const numbers = [1, 2, 3, 4, 5, 6];
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4, 6]
Find js (поиск в javascript)
Колбэк принимает три аргумента: текущий элемент, индекс и сам массив. Пример с индексом:
const items = ['a', 'b', 'c', 'd'];
const filteredByIndex = items.filter((item, index) => index < 2);
console.log(filteredByIndex); // ['a', 'b']
Js примеры (примеры кода на javascript)
Типичные ошибки:
- Забывают возвращать значение из колбэка - возвращается undefined, что интерпретируется как false, и массив становится пустым.
- Изменение исходного массива внутри колбэка (побочные эффекты) - это противоречит функциональному стилю и может привести к неожиданным результатам.
- Использование
filter()на разреженных массивах - метод пропускает пустые слоты, что иногда бывает неочевидно.
Решение: всегда возвращать булево значение, избегать мутаций, для разреженных массивов использовать Array.from() или flat() предварительно.
Как отфильтровать массив с помощью цикла for?
Классический подход без использования методов высшего порядка. Может быть полезен для лучшего понимания или в средах, где нужна полная поддержка старых браузеров.
const numbers = [1, 2, 3, 4, 5];
const oddNumbers = [];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] % 2 !== 0) {
oddNumbers.push(numbers[i]);
}
}
console.log(oddNumbers); // [1, 3, 5]
Javascript строки (строки в javascript)
Проблема: необходимо вручную управлять индексом и создавать новый массив. Ошибки: off-by-one, забыли инициализировать массив, случайно использовали var вместо let.
Как отфильтровать массив с помощью reduce?
Метод reduce() также подходит для фильтрации, аккумулируя отобранные элементы.
const numbers = [10, 15, 20, 25];
const greaterThan18 = numbers.reduce((acc, num) => {
if (num > 18) acc.push(num);
return acc;
}, []);
console.log(greaterThan18); // [20, 25]
Js фильтр (фильтрация в javascript)
Такой вариант даёт гибкость: можно одновременно фильтровать и трансформировать данные.
Ошибки: забыть вернуть аккумулятор, случайно мутировать исходный массив. Использование reduce для простой фильтрации менее читаемо, чем filter.
Как отфильтровать массив, используя forEach и условие?
Метод forEach сам по себе ничего не возвращает, но можно заполнять внешний массив.
const numbers = [7, 12, 18, 21];
const filtered = [];
numbers.forEach(num => {
if (num >= 18) filtered.push(num);
});
console.log(filtered); // [18, 21]
Meta js (мета-теги в javascript)
Такой подход понятен, но уступает filter в выразительности.
Проблема: forEach не поддерживает прерывание (break/continue), поэтому для больших массивов с ранним выходом лучше использовать цикл for или some/every.
Как отфильтровать массив объектов по нескольким условиям?
Часто требуется комбинировать критерии. Метод filter отлично справляется с этим через логические операторы.
const users = [
{ name: 'Иван', age: 25, active: true },
{ name: 'Мария', age: 17, active: true },
{ name: 'Пётр', age: 30, active: false }
];
const adultActive = users.filter(user => user.age >= 18 && user.active);
console.log(adultActive);
// [{ name: 'Иван', age: 25, active: true }]
Href javascript (ссылки javascript)
Ошибка: при сравнении строк по алфавиту или неверном использовании === вместо == для числовых/строковых преобразований.
Как отфильтровать массив, удаляя дубликаты?
Комбинируя filter и indexOf (или Set для более эффективного решения).
const array = [1, 2, 2, 3, 1, 4];
const unique = array.filter((item, index) => array.indexOf(item) === index);
console.log(unique); // [1, 2, 3, 4]
Js приложения (приложения на javascript)
Для больших массивов лучше использовать Set:
const unique = [...new Set(array)];
Проблема с indexOf: для объектов (непримитивов) работает только по ссылке, а не по значению.
Расширенные примеры фильтрации в JavaScript
Дополнительные сценарии, включающие работу с вложенными структурами, асинхронные условия и оптимизацию.
Как отфильтровать массив по вложенному свойству?
const orders = [
{ id: 1, items: [{ price: 100 }, { price: 50 }] },
{ id: 2, items: [{ price: 200 }] },
{ id: 3, items: [] }
];
// Заказы, где сумма цен items > 150
const expensiveOrders = orders.filter(order =>
order.items.reduce((sum, item) => sum + item.price, 0) > 150
);
console.log(expensiveOrders);
// [ { id: 1, items: [ { price: 100 }, { price: 50 } ] }, { id: 2, items: [ { price: 200 } ] } ]
[ { id: 1, items: [ { price: 100 }, { price: 50 } ] }, { id: 2, items: [ { price: 200 } ] } ]
Как отфильтровать массив с использованием асинхронного условия (например, проверка по API)?
Метод filter синхронный, поэтому для асинхронных проверок нужно комбинировать с Promise.all и map.
const urls = ['https://api.example.com/1', 'https://api.example.com/2'];
async function filterAsync(arr, asyncPredicate) {
const results = await Promise.all(arr.map(async (item, index) => ({
item,
keep: await asyncPredicate(item, index)
})));
return results.filter(r => r.keep).map(r => r.item);
}
// Пример: оставить только URL, отвечающие статусом 200
const reachableUrls = await filterAsync(urls, async (url) => {
try {
const response = await fetch(url);
return response.ok;
} catch {
return false;
}
});
console.log(reachableUrls);
Как отфильтровать массив по нескольким динамическим критериям?
const products = [
{ name: 'Телефон', price: 30000, inStock: true },
{ name: 'Ноутбук', price: 60000, inStock: false },
{ name: 'Планшет', price: 20000, inStock: true }
];
const filters = {
maxPrice: 25000,
inStockOnly: true
};
const filtered = products.filter(product => {
let valid = true;
if (filters.maxPrice !== undefined) {
valid = valid && product.price <= filters.maxPrice;
}
if (filters.inStockOnly) {
valid = valid && product.inStock;
}
return valid;
});
console.log(filtered);
// [ { name: 'Планшет', price: 20000, inStock: true } ]
[ { name: 'Планшет', price: 20000, inStock: true } ]
Как отфильтровать массив строк по регулярному выражению?
const texts = ['apple', 'banana', 'apricot', 'cherry'];
const startsWithA = texts.filter(t => /^a/i.test(t));
console.log(startsWithA); // ['apple', 'apricot']
['apple', 'apricot']
Как отфильтровать массив, используя отрицательное условие (исключение)?
const numbers = [1, 2, 3, 4, 5];
const notThreeOrFour = numbers.filter(n => n !== 3 && n !== 4);
console.log(notThreeOrFour); // [1, 2, 5]
[1, 2, 5]
Как отфильтровать массив по нескольким индексам (выбрать элементы на определённых позициях)?
const arr = ['a', 'b', 'c', 'd', 'e'];
const indices = [0, 2, 4];
const selected = arr.filter((_, i) => indices.includes(i));
console.log(selected); // ['a', 'c', 'e']
['a', 'c', 'e']
Как отфильтровать массив объектов со вложенными массивами (например, пользователи и их теги)?
const users = [
{ name: 'Ольга', tags: ['js', 'css'] },
{ name: 'Сергей', tags: ['html'] },
{ name: 'Анна', tags: ['js', 'react'] }
];
// Пользователи, у которых есть тег 'js'
const jsUsers = users.filter(user => user.tags.includes('js'));
console.log(jsUsers);
// [ { name: 'Ольга', tags: ['js', 'css'] }, { name: 'Анна', tags: ['js', 'react'] } ]
[ { name: 'Ольга', tags: ['js', 'css'] }, { name: 'Анна', tags: ['js', 'react'] } ]