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

Реализуйте filter для массива

1.0 Junior🔥 221 комментариев
#Node.js и JavaScript#Алгоритмы и структуры данных

Условие

Реализуйте метод Array.prototype.myFilter, который работает аналогично встроенному filter:

Array.prototype.myFilter = function(callback) {
  // Ваш код
};

// Примеры:
const evens = [1, 2, 3, 4, 5].myFilter(x => x % 2 === 0);
console.log(evens); // [2, 4]

const positive = [-1, 0, 1, 2, -3].myFilter(x => x > 0);
console.log(positive); // [1, 2]

Что проверяется

  • Понимание работы filter
  • Работа с прототипами
  • Callback-функции с индексом и массивом

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

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

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

Решение

Полная реализация

Array.prototype.myFilter = function<T>(callback: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[] {
  const result: T[] = [];
  
  for (let i = 0; i < this.length; i++) {
    // Проверяем, что элемент существует в массиве (важно для разреженных массивов)
    if (i in this) {
      // Вызываем callback с контекстом thisArg, если передан
      const shouldInclude = callback.call(thisArg, this[i], i, this);
      
      // Если callback вернул truthy значение, добавляем элемент в результат
      if (shouldInclude) {
        result.push(this[i]);
      }
    }
  }
  
  return result;
};

Ключевые моменты реализации

1. Итерация через элементы

  • Используем обычный for цикл для перебора всех индексов
  • Проверка i in this необходима для корректной работы с разреженными массивами (sparse arrays), где есть пропуски

2. Callback с правильными параметрами

  • callback(value, index, array) — функция получает три аргумента
  • Контекст вызова контролируется через call(thisArg, ...)
  • thisArg позволяет задать значение this внутри callback

3. Условное добавление элемента

  • Проверяем результат callback
  • Если он truthy (истинное значение), добавляем элемент в результирующий массив
  • Сохраняется исходный порядок элементов

Примеры использования

// Пример 1: Фильтрация чётных чисел
const evens = [1, 2, 3, 4, 5].myFilter(x => x % 2 === 0);
console.log(evens); // [2, 4]

// Пример 2: Фильтрация положительных чисел
const positive = [-1, 0, 1, 2, -3].myFilter(x => x > 0);
console.log(positive); // [1, 2]

// Пример 3: Использование индекса
const indexed = ['a', 'b', 'c'].myFilter((x, i) => i % 2 === 0);
console.log(indexed); // ['a', 'c']

// Пример 4: С контекстом thisArg
const obj = { threshold: 5 };
const filtered = [1, 5, 10, 3].myFilter(function(x) {
  return x > this.threshold;
}, obj);
console.log(filtered); // [10]

Разница с наивной реализацией

Частая ошибка — забыть про разреженные массивы:

// ❌ Неправильно: обрабатывает пустые слоты
Array.prototype.myFilter = function(callback) {
  const result = [];
  for (let i = 0; i < this.length; i++) {
    if (callback(this[i], i, this)) {
      result.push(this[i]);
    }
  }
  return result;
};

// При пропуске слота this[i] будет undefined
const sparse = [1, , 3];
sparse.myFilter(x => x > 0); // [1, undefined] ❌

// ✅ Правильно: проверяем наличие элемента
if (i in this) {
  // только если элемент существует
}

Производительность и особенности

  • Сложность: O(n) — один проход по массиву
  • Память: O(m), где m — количество элементов, прошедших фильтр
  • Не мутирует исходный массив — создаёт новый
  • Совместимость с thisArg улучшает гибкость при работе с методами класса
Реализуйте filter для массива | PrepBro