0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Последняя функция из нашей тройки -<a>array_reduce</a>или<strong>свертка</strong>. В других языках она называется accumulate или fold. Эта функция используется для<strong>агрегации</strong>. Она устроена немного сложнее, чем map и filter, но сохраняет общий подход с передачей функции.</p>
1
<p>Последняя функция из нашей тройки -<a>array_reduce</a>или<strong>свертка</strong>. В других языках она называется accumulate или fold. Эта функция используется для<strong>агрегации</strong>. Она устроена немного сложнее, чем map и filter, но сохраняет общий подход с передачей функции.</p>
2
<p>Как обычно, начнем с примера на циклах. Реализуем код, находящий самого взрослого пользователя:</p>
2
<p>Как обычно, начнем с примера на циклах. Реализуем код, находящий самого взрослого пользователя:</p>
3
<p>Основное отличие агрегации от отображения и фильтрации заключается в том, что результатом агрегации может быть любой тип данных - как примитивный, так и составной. Например, результатом может быть массив. Кроме того, агрегация нередко подразумевает инициализацию начальным значением. В примере выше она выполняется на строчке $oldest = $users[0];.</p>
3
<p>Основное отличие агрегации от отображения и фильтрации заключается в том, что результатом агрегации может быть любой тип данных - как примитивный, так и составной. Например, результатом может быть массив. Кроме того, агрегация нередко подразумевает инициализацию начальным значением. В примере выше она выполняется на строчке $oldest = $users[0];.</p>
4
<p>Посмотрим еще один пример агрегации - группировку имен пользователей по возрасту:</p>
4
<p>Посмотрим еще один пример агрегации - группировку имен пользователей по возрасту:</p>
5
<p>В этом примере результатом агрегации становится массив массивов, который в самом начале инициируется пустым массивом. Значение, которое накапливает результат агрегации, принято называть словом<strong>аккумулятор</strong>. В примерах выше это $oldest и $usersByAge.</p>
5
<p>В этом примере результатом агрегации становится массив массивов, который в самом начале инициируется пустым массивом. Значение, которое накапливает результат агрегации, принято называть словом<strong>аккумулятор</strong>. В примерах выше это $oldest и $usersByAge.</p>
6
<p>Реализуем первый пример, используя array_reduce:</p>
6
<p>Реализуем первый пример, используя array_reduce:</p>
7
<p>Функция array_reduce принимает на вход три параметра. Два из них уже традиционны - это коллекция и функция-обработчик, а вот третьим выступает начальное значение аккумулятора. Поиск самого взрослого пользователя аналогичен поиску максимального или минимального числа в массиве. Соответственно, аккумулятор должен быть инициализирован первым пользователем. Этот же аккумулятор возвращается наружу.</p>
7
<p>Функция array_reduce принимает на вход три параметра. Два из них уже традиционны - это коллекция и функция-обработчик, а вот третьим выступает начальное значение аккумулятора. Поиск самого взрослого пользователя аналогичен поиску максимального или минимального числа в массиве. Соответственно, аккумулятор должен быть инициализирован первым пользователем. Этот же аккумулятор возвращается наружу.</p>
8
<p>Колбэк-функция, передаваемая в array_reduce - это самая важная часть и ключ к пониманию работы всего механизма агрегации. Она принимает на вход два значения:</p>
8
<p>Колбэк-функция, передаваемая в array_reduce - это самая важная часть и ключ к пониманию работы всего механизма агрегации. Она принимает на вход два значения:</p>
9
<ul><li>Текущее значение аккумулятора</li>
9
<ul><li>Текущее значение аккумулятора</li>
10
<li>Текущий обрабатываемый элемент</li>
10
<li>Текущий обрабатываемый элемент</li>
11
</ul><p>Задача функции - вернуть новое значение аккумулятора. При этом array_reduce никак не анализирует содержимое аккумулятора. Все, что она делает - она передает значение аккумулятора в каждый новый вызов, пока не будет обработана вся коллекция, и в конце концов вернет его наружу. Подчеркнем, что возвращать аккумулятор надо всегда, даже если он не изменился.</p>
11
</ul><p>Задача функции - вернуть новое значение аккумулятора. При этом array_reduce никак не анализирует содержимое аккумулятора. Все, что она делает - она передает значение аккумулятора в каждый новый вызов, пока не будет обработана вся коллекция, и в конце концов вернет его наружу. Подчеркнем, что возвращать аккумулятор надо всегда, даже если он не изменился.</p>
12
<p>Второй пример с использованием array_reduce выглядит так:</p>
12
<p>Второй пример с использованием array_reduce выглядит так:</p>
13
<p>Код практически не изменился. Как видите, ушел цикл и появился возврат аккумулятора из анонимной функции.</p>
13
<p>Код практически не изменился. Как видите, ушел цикл и появился возврат аккумулятора из анонимной функции.</p>
14
<p>Перейдем к реализации:</p>
14
<p>Перейдем к реализации:</p>
15
<p>Функция array_reduce очень мощная. Формально, можно работать, используя только ее, потому что она может заменить<strong>отображение</strong>и<strong>фильтрацию</strong>. Но делать так не стоит. Агрегация управляет состоянием (аккумулятором) явно. Такой код всегда сложнее и требует больше действий. Поэтому, если задачу возможно решить отображением или фильтрацией, то так и нужно делать.</p>
15
<p>Функция array_reduce очень мощная. Формально, можно работать, используя только ее, потому что она может заменить<strong>отображение</strong>и<strong>фильтрацию</strong>. Но делать так не стоит. Агрегация управляет состоянием (аккумулятором) явно. Такой код всегда сложнее и требует больше действий. Поэтому, если задачу возможно решить отображением или фильтрацией, то так и нужно делать.</p>