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

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

2.2 Middle🔥 251 комментариев
#Node.js и JavaScript#Алгоритмы и структуры данных#ООП

Условие

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

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

// Примеры:
const sum = [1, 2, 3, 4].myReduce((acc, val) => acc + val, 0);
console.log(sum); // 10

const max = [5, 1, 9, 3].myReduce((acc, val) => val > acc ? val : acc);
console.log(max); // 9

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

  • Понимание работы reduce
  • Работа с прототипами
  • Обработка случая без initialValue

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

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

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

Решение: Array.prototype.myReduce

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

Array.prototype.myReduce = function(callback, initialValue) {
  // Базовые проверки
  if (this == null) {
    throw new TypeError('Array.prototype.reduce called on null or undefined');
  }
  
  if (typeof callback !== 'function') {
    throw new TypeError(callback + ' is not a function');
  }
  
  const array = Object(this);
  const length = array.length >>> 0; // Convert to unsigned 32-bit int
  
  let accumulator;
  let startIndex = 0;
  
  // Определяем начальное значение
  if (arguments.length >= 2) {
    accumulator = initialValue;
  } else {
    // Ищем первый элемент (пропускаем пустые слоты)
    if (length === 0) {
      throw new TypeError('Reduce of empty array with no initial value');
    }
    
    let found = false;
    for (let i = 0; i < length; i++) {
      if (i in array) {
        accumulator = array[i];
        startIndex = i + 1;
        found = true;
        break;
      }
    }
    
    if (!found) {
      throw new TypeError('Reduce of empty array with no initial value');
    }
  }
  
  // Основной цикл reduce
  for (let i = startIndex; i < length; i++) {
    if (i in array) {
      accumulator = callback(accumulator, array[i], i, array);
    }
  }
  
  return accumulator;
};

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

// Пример 1: Сумма с initialValue
const sum = [1, 2, 3, 4].myReduce((acc, val) => acc + val, 0);
console.log(sum); // 10

// Пример 2: Максимум без initialValue
const max = [5, 1, 9, 3].myReduce((acc, val) => val > acc ? val : acc);
console.log(max); // 9

// Пример 3: Объединение объектов
const grouped = ['a', 'ab', 'b', 'ba'].myReduce((acc, word) => {
  const key = word[0];
  (acc[key] = acc[key] || []).push(word);
  return acc;
}, {});
// { a: ['a', 'ab'], b: ['b', 'ba'] }

// Пример 4: Логирование
const logged = [1, 2, 3].myReduce((acc, val, i) => {
  console.log(`i=${i}: ${acc} + ${val} = ${acc + val}`);
  return acc + val;
}, 0);
// i=0: 0 + 1 = 1
// i=1: 1 + 2 = 3
// i=2: 3 + 3 = 6

Ключевые особенности

1. arguments.length для различия undefined

  • Если initialValue явно передан (даже если undefined), используем его
  • Если не передан, берём первый элемент массива

2. Поддержка разреженных массивов

  • Проверка i in array пропускает пустые слоты
  • Callback вызывается только для существующих элементов

3. Обработка ошибок

  • Пустой массив без initialValue выбросит ошибку
  • Проверка типа callback
  • Проверка null/undefined на this

Отличие от других методов

  • map: преобразует каждый элемент
  • filter: выбирает элементы по условию
  • reduce: накапливает единственное значение из всех элементов
  • reduce — универсален, через него можно реализовать map и filter

Тестирование

// С initialValue
test('[1,2,3].myReduce((a,b) => a+b, 0) === 6');

// Без initialValue
test('[1,2,3].myReduce((a,b) => a+b) === 6');

// Пустой массив с initialValue
test('[].myReduce((a,b) => a+b, 0) === 0');

// Пустой массив без initialValue → Error
test('[].myReduce((a,b) => a+b) throws');

// Разреженный массив
test('[1,,3].myReduce((a,b) => a+b) === 4');