Get Mystery Box with random crypto!

На момент написания этого разбора 68% участников опроса ответи | fomin

На момент написания этого разбора 68% участников опроса ответили, что .reduce() возвращает любой тип данных. Радует, что это большинство, но процент мог бы быть больше

Я думал, что основным вариантом окажется number, однако он занял только второе место в опросе.

Почему number? Потому что каждый первый пример того, как работает reduce, описан на примере, как получить сумму всех элементов массива.

[1, 2, 3, 4].reduce((acc, item) => acc+= item);

// Результат: 10

Попробуем разобраться.

Метод reduce принимает коллбек, который будет вызываться на каждой итерации при переборе массива.

Первым аргументом этот коллбек принимает так называемый аккумулятор. Его часто пытаются наделить какими-то особенными свойствами, однако это обычная переменная, в которую мы можем что-то записать, и это "что-то" не обнуляется при следующем вызове коллбека, а остаётся. Таким образом, при каждом вызове коллбека мы можем что-то записывать в эту переменную, накапливая значения либо перезаписывая прошлое значение (это уже как мы решим).

Второй, третий и четвертый аргументы коллбека такие же, как и у .map(): сам элемент, на котором вызывается коллбек, его индекс и полностью весь массив.

Помимо коллбека, reduce принимает вторым аргументом значение по умолчанию. Это значение, которое будет записано при инициализации в аккумулятор.

[1, 2, 3, 4].reduce((acc, item) => acc+= item, 0);

Теперь в конце, после коллбека, я передаю значение 0 как стартовое значение для аккумулятора.

Ну вот reduce и возвращает number. В чём подвох?

Массив может состоять из каких угодно элементов, хотя на самом деле это даже не важно, ведь мы можем в аккумулятор накапливать что угодно, не зависимо от того, какой массив мы перебираем.

Что всё-таки вернёт reduce?

0. Число

1. Строку

[1, 2, 3, 4].reduce((acc, item) => {
acc += `Слово${item}`;
return acc;
}, '');

// Результат: "Слово1Слово2Слово3Слово4"

2. Массив

[1, 2, 3, 4].reduce((acc, item) => {
acc.push(item * 2);
return acc;
}, []);

// Результат: [2, 4, 6, 8]

3. Объект

[1, 2, 3, 4].reduce((acc, item) => {
acc[`value-${item}`] = item;
return acc;
}, {});

// Результат: {value-1: 1, value-2: 2, value-3: 3, value-4: 4}

4. Undefined

[1, 2, 3, 4].reduce((acc, item) => {
acc = undefined;
return acc;
});

// Результат: undefined

По такому же примеру можно вернуть любой тип данных. Хоть он и достаточно синтетический, но он отлично отражает то, что reduce вернёт что угодно. Любое значение, которое будет записано в аккумулятор.

А вообще с помощью reduce можно решать много интересных задачек. Какие вам приходилось решать? Делитесь в комментариях