ReduceRight: примеры (JAVASCRIPT)

Полное руководство по JavaScript reduceRight с практическими примерами
Раздел: Массивы, Агрегация
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T

Основные сведения о reduceRight

Метод reduceRight() применяется к массивам в JavaScript. Он выполняет callback-функцию для каждого элемента, двигаясь справа налево (от последнего к первому). В результате работы формируется единое итоговое значение.

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

Синтаксис метода: arr.reduceRight(callback[, initialValue]).

Аргументы callback-функции:

  • accumulator (аккумулятор) — накапливает результат вызовов. На первом вызове, если передан initialValue, равен ему, иначе равен последнему элементу массива.
  • currentValue (текущий элемент) — значение обрабатываемого элемента.
  • index (индекс) — позиция текущего элемента в массиве.
  • array (массив) — исходный массив, к которому применяется метод.

Необязательный аргумент initialValue задает начальное значение аккумулятора для первого вызова. Если массив пустой и initialValue не указан, генерируется ошибка TypeError.

Метод возвращает конечное значение аккумулятора.

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

Соединение строк с конца массива:

const letters = ['д', 'о', 'б', 'а']; 
const result = letters.reduceRight((acc, cur) => acc + cur); 
console.log(result);
'абод'

Вычитание чисел с указанием начального значения:

const numbers = [2, 5, 10]; 
const result = numbers.reduceRight((acc, num) => acc - num, 100); 
console.log(result);
83 // 100 - 10 - 5 - 2

Работа с вложенными массивами:

const nested = [[1, 2], [3, 4], [5, 6]]; 
const flat = nested.reduceRight((acc, cur) => acc.concat(cur), []); 
console.log(flat);
[5, 6, 3, 4, 1, 2]

Похожие методы в JavaScript

reduce() — выполняет аналогичную операцию, но обходит массив слева направо. Выбор между reduce и reduceRight зависит от требуемого направления обработки данных.

forEach() — просто перебирает элементы без аккумуляции результата. Используется для побочных действий над элементами.

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

for...of — циклическая конструкция, обеспечивающая полный контроль над процессом итерации, но с более подробным синтаксисом.

Частые ошибки

Ошибка при работе с пустым массивом без начального значения:

[].reduceRight((acc, cur) => acc + cur); 
// TypeError: Reduce of empty array with no initial value
TypeError

Использование метода для объектов, не являющихся массивами:

const obj = {0: 'a', 1: 'b', length: 2};
Array.prototype.reduceRight.call(obj, (acc, cur) => acc + cur, ''); // Работает
obj.reduceRight((acc, cur) => acc + cur); // Ошибка
TypeError: obj.reduceRight is not a function

Неизменение исходного массива внутри callback-функции может привести к неочевидному поведению:

const arr = [1, 2, 3, 4];
const result = arr.reduceRight((acc, cur, idx, array) => {
    array.pop(); // Модификация исходного массива
    return acc + cur;
}, 0);
console.log(result, arr);
7 [] // Результат 4+3, массив очищен

Изменения в спецификации

Существенных изменений в работе метода reduceRight() в последних версиях ECMAScript не было. Метод стабильно работает с момента стандартизации в ES5.1.

Уточнения касались особенностей обработки разреженных массивов и вызова callback-функции только для существующих элементов.

Расширенные примеры применения

Построение HTML-списка с конца массива данных:

Пример javascript
const items = ['Первый', 'Второй', 'Третий'];
const htmlList = items.reduceRight((acc, text) => 
    acc + `<li>${text}</li>\n`, '');
console.log(`<ul>\n${htmlList}</ul>`);
<ul>
<li>Третий</li>
<li>Второй</li>
<li>Первый</li>
</ul>

Последовательное применение функций из массива справа налево (композиция):

Пример javascript
const functions = [
    x => x * 2,
    x => x - 1,
    x => x + 5
];
const compose = functions.reduceRight((acc, fn) => 
    (value) => fn(acc(value)), 
    x => x
);
console.log(compose(10)); // (10 + 5 - 1) * 2
28

Рекурсивное выравнивание многомерного массива с сохранением обратного порядка:

Пример javascript
function flattenRight(arr) {
    return arr.reduceRight((acc, val) => 
        acc.concat(Array.isArray(val) ? flattenRight(val) : val), []);
}
console.log(flattenRight([1, [2, [3, 4], 5], 6]));
[6, 5, 4, 3, 2, 1]

Поиск индекса с конца с учетом условия:

Пример javascript
const data = [10, 25, 30, 45, 20];
const lastIndexOver25 = data.reduceRight((foundIndex, cur, idx) => 
    foundIndex === -1 && cur > 25 ? idx : foundIndex, -1
);
console.log(lastIndexOver25);
3 // индекс элемента 45

Аналоги в других языках программирования

Python: Функция functools.reduce() с указанием начального значения. Для обработки справа можно предварительно развернуть последовательность с помощью reversed().

from functools import reduce
result = reduce(lambda acc, cur: acc - cur, reversed([2, 5, 10]), 100)
print(result)
83

PHP: Функция array_reduce(). Для обработки справа применяется array_reverse() перед восстановлением.

$numbers = [2, 5, 10];
$result = array_reduce(array_reverse($numbers), function($acc, $cur) { 
    return $acc - $cur;
}, 100);
echo $result;
83

C# (LINQ): Метод Aggregate(). Для обработки в обратном порядке используется Reverse().

int[] numbers = { 2, 5, 10 };
var result = numbers.Reverse().Aggregate(100, (acc, cur) => acc - cur);
Console.WriteLine(result);
83

JS reduceRight function comments

En
ReduceRight Applies a function against an accumulator and each value of the array (from right-to-left) to reduce it to a single value