HTML Diff
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>