Фильтрация массивов в JavaScript: все способы и практические примеры

Раздел: JavaScript -> Основы языка 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'] } ]

Фильтрация в JavaScript - comments

En
Js фильтр (javascript)