← Назад к вопросам

Как работает Filter?

2.0 Middle🔥 161 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как работает Array.filter() в JavaScript

Array.filter() — одна из самых полезных функций для работы с массивами. Она создает новый массив, содержащий только элементы, которые соответствуют определенному условию. Важно понимать, как она работает на уровне, чтобы написать эффективный код.

Базовая синтаксис и механика

Filter принимает callback-функцию, которая вызывается для каждого элемента массива. Если функция вернула true, элемент включается в новый массив.

const numbers = [1, 2, 3, 4, 5];

// Базовый пример
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]

// Со всеми параметрами
const result = numbers.filter((element, index, array) => {
  console.log(`element: ${element}, index: ${index}, array: ${array}`);
  return element > 2;
});

// element: 1, index: 0, array: 1,2,3,4,5
// element: 2, index: 1, array: 1,2,3,4,5
// element: 3, index: 2, array: 1,2,3,4,5
// ...
console.log(result); // [3, 4, 5]

Важные свойства filter()

1. Не изменяет исходный массив (immutable)

const original = [1, 2, 3, 4, 5];
const filtered = original.filter(n => n > 2);

console.log(original); // [1, 2, 3, 4, 5] — не изменился
console.log(filtered); // [3, 4, 5] — новый массив

2. Пропускает пустые элементы в sparse array

const sparse = [1, , 3, , 5];
const result = sparse.filter(x => x > 1);

// Пустые элементы пропускаются
console.log(result); // [3, 5] — индексы 1 и 3 пропущены

3. Порядок сохраняется, но индексы меняются

const arr = ['a', 'b', 'c'];
arr.forEach((_, i) => console.log(i)); // 0, 1, 2

const filtered = arr.filter(x => x !== 'b');
filtered.forEach((_, i) => console.log(i)); // 0, 1 — индекс 'c' стал 1

Примеры с разными типами данных

Фильтрация объектов

const users = [
  { id: 1, name: 'Alice', age: 25 },
  { id: 2, name: 'Bob', age: 17 },
  { id: 3, name: 'Charlie', age: 30 }
];

const adults = users.filter(user => user.age >= 18);
console.log(adults);
// [
//   { id: 1, name: 'Alice', age: 25 },
//   { id: 3, name: 'Charlie', age: 30 }
// ]

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

const words = ['apple', 'banana', 'apricot', 'cherry'];

// Слова, начинающиеся на 'a'
const startsWithA = words.filter(word => word.startsWith('a'));
console.log(startsWithA); // ['apple', 'apricot']

// Слова длиной > 5 символов
const longWords = words.filter(word => word.length > 5);
console.log(longWords); // ['banana', 'apricot', 'cherry']

Удаление дубликатов с filter

const numbers = [1, 2, 2, 3, 3, 3, 4];

const unique = numbers.filter((num, index, arr) => {
  return arr.indexOf(num) === index;
});

console.log(unique); // [1, 2, 3, 4]
// indexOf возвращает первый индекс, поэтому дубликаты фильтруются

Производительность и оптимизация

Проблема: filter() создает новый массив

// Неэффективно: создаём промежуточный массив
const result = data
  .filter(x => x > 10)
  .map(x => x * 2)
  .filter(x => x < 100);

// Эффективнее: одна итерация с reduce
const result = data.reduce((acc, x) => {
  if (x > 10) {
    const doubled = x * 2;
    if (doubled < 100) {
      acc.push(doubled);
    }
  }
  return acc;
}, []);

Для больших массивов рассмотри for loop

// for loop быстрее для очень больших массивов
const filtered = [];
for (let i = 0; i < array.length; i++) {
  if (condition(array[i])) {
    filtered.push(array[i]);
  }
}

Пример: фильтрация в React компоненте

function UserList({ users, filterRole }) {
  // Фильтруем пользователей при каждом рендере
  const filteredUsers = users.filter(user => user.role === filterRole);

  return (
    <ul>
      {filteredUsers.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

// Оптимизированная версия с useMemo
function OptimizedUserList({ users, filterRole }) {
  const filteredUsers = useMemo(
    () => users.filter(user => user.role === filterRole),
    [users, filterRole]
  );

  return (
    <ul>
      {filteredUsers.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

Цепочка filter и map

const products = [
  { id: 1, name: 'Laptop', price: 1000, inStock: true },
  { id: 2, name: 'Mouse', price: 25, inStock: false },
  { id: 3, name: 'Keyboard', price: 80, inStock: true }
];

// Цепочка: фильтруем по наличию, затем трансформируем
const available = products
  .filter(product => product.inStock)
  .map(product => ({
    ...product,
    discountedPrice: product.price * 0.9
  }));

console.log(available);
// [
//   { id: 1, name: 'Laptop', price: 1000, inStock: true, discountedPrice: 900 },
//   { id: 3, name: 'Keyboard', price: 80, inStock: true, discountedPrice: 72 }
// ]

Мой подход к использованию filter()

  1. Используй для фильтрации данных — это читаемо и декларативно
  2. Комбинируй с map() и reduce() для сложных трансформаций
  3. Кэшируй результат фильтрации в React с useMemo, если список большой
  4. Для очень больших данных рассмотри оптимизацию (индексирование, виртуализация)
  5. Не делай сложную логику в filter() — выноси в отдельные функции для читаемости

Filter — это идеальный инструмент для работы с массивами в функциональном стиле. Но помни о производительности при работе с большими наборами данных.

Как работает Filter? | PrepBro