Array reduce: примеры (PHP)

Полное руководство по array_reduce в PHP с практическими примерами
Раздел: Работа с массивами
array_reduce(array $array, callable $callback, mixed $initial = null): mixed

Основные сведения о функции array_reduce

Функция array_reduce применяется для итеративной обработки элементов массива с использованием callback-функции, которая последовательно обрабатывает элементы и возвращает единственное значение. Эта функция часто используется для агрегации данных, вычисления сумм, произведений, конкатенации строк и других операций свертки.

Синтаксис и параметры

Синтаксис функции: array_reduce(array $array, callable $callback, mixed $initial = null): mixed

Параметры:

  • $array - обрабатываемый массив
  • $callback - callback-функция, принимающая два параметра: промежуточный результат ($carry) и текущий элемент массива ($item)
  • $initial - необязательное начальное значение. Если массив пуст, это значение будет возвращено

Callback-функция вызывается для каждого элемента массива, получая текущее значение аккумулятора и элемент массива, возвращая новое значение аккумулятора.

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

Пример 1: Сумма элементов
<?php
$numbers = [1, 2, 3, 4, 5];
$sum = array_reduce($numbers, function($carry, $item) {
    return $carry + $item;
}, 0);
echo $sum;
?>
15
Пример 2: Конкатенация строк
<?php
$words = ["Hello", "World", "!"];
$sentence = array_reduce($words, function($carry, $item) {
    return $carry . " " . $item;
}, "");
echo trim($sentence);
?>
Hello World !
Пример 3: Поиск максимального значения
<?php
$numbers = [10, 5, 25, 3, 18];
$max = array_reduce($numbers, function($carry, $item) {
    return $carry === null || $item > $carry ? $item : $carry;
});
echo $max;
?>
25
Пример 4: Использование с анонимной функцией и начальным значением
<?php
$data = [2, 3, 4];
$product = array_reduce($data, function($carry, $item) {
    return $carry * $item;
}, 1);
echo $product;
?>
24

Альтернативные функции в PHP

В PHP существуют другие функции для обработки массивов, которые могут использоваться в похожих сценариях:

array_walk и array_walk_recursive

Функции для применения пользовательской функции к каждому элементу массива. В отличие от array_reduce, они не возвращают агрегированное значение, а модифицируют элементы непосредственно.

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

Фильтрует элементы массива с использованием callback-функции. Возвращает массив с элементами, прошедшими проверку.

array_sum, array_product

Специализированные функции для вычисления суммы и произведения элементов массива. Используются вместо array_reduce для простых арифметических операций.

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

Типичные ошибки и проблемы

Ошибка 1: Неправильный тип возвращаемого значения
<?php
$array = [1, 2, 3];
$result = array_reduce($array, function($carry, $item) {
    echo $item; // Побочный эффект вместо возврата
}, 0);
var_dump($result);
?>
NULL

Callback-функция должна возвращать значение, иначе результат будет неопределенным.

Ошибка 2: Обработка пустого массива без начального значения
<?php
$emptyArray = [];
$result = array_reduce($emptyArray, function($carry, $item) {
    return $carry + $item;
});
var_dump($result);
?>
NULL

При обработке пустого массива без указания начального значения функция вернет NULL.

Ошибка 3: Изменение исходного массива внутри callback
<?php
$numbers = [1, 2, 3];
$sum = array_reduce($numbers, function($carry, $item) use (&$numbers) {
    $numbers[] = $item * 2; // Модификация исходного массива
    return $carry + $item;
}, 0);
print_r($numbers);
?>

Изменение массива во время его обработки может привести к неожиданному поведению.

Изменения в последних версиях PHP

PHP 8.0: Более строгая типизация

В PHP 8.0 улучшена обработка типов параметров. Некорректные типы в callback-функции теперь вызывают TypeError.

PHP 7.0: Поддержка скалярных типов

Добавлена возможность указывать типы параметров в callback-функциях, что улучшает проверку кода.

PHP 5.3: Поддержка анонимных функций

Версия 5.3 ввела анонимные функции, что значительно упростило использование array reduce с inline callback.

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

Пример 1: Группировка данных
Пример php
<?php
$students = [
    ['name' => 'Алексей', 'grade' => 'A'],
    ['name' => 'Мария', 'grade' => 'B'],
    ['name' => 'Иван', 'grade' => 'A'],
    ['name' => 'Ольга', 'grade' => 'C']
];

$grouped = array_reduce($students, function($carry, $item) {
    $carry[$item['grade']][] = $item['name'];
    return $carry;
}, []);

print_r($grouped);
?>
Array
(
    [A] => Array
        (
            [0] => Алексей
            [1] => Иван
        )
    [B] => Array
        (
            [0] => Мария
        )
    [C] => Array
        (
            [0] => Ольга
        )
)
Пример 2: Создание HTML-списка
Пример php
<?php
$items = ['Яблоки', 'Бананы', 'Апельсины'];
$htmlList = array_reduce($items, function($carry, $item) {
    return $carry . "<li>" . htmlspecialchars($item) . "</li>";
}, "<ul>") . "</ul>";
echo $htmlList;
?>
<ul><li>Яблоки</li><li>Бананы</li><li>Апельсины</li></ul>
Пример 3: Вычисление факториала
Пример php
<?php
$n = 5;
$range = range(1, $n);
$factorial = array_reduce($range, function($carry, $item) {
    return $carry * $item;
}, 1);
echo "Факториал $n = $factorial";
?>
Факториал 5 = 120
Пример 4: Построение дерева из плоского массива
Пример php
<?php
$categories = [
    ['id' => 1, 'name' => 'Электроника', 'parent_id' => 0],
    ['id' => 2, 'name' => 'Телефоны', 'parent_id' => 1],
    ['id' => 3, 'name' => 'Ноутбуки', 'parent_id' => 1],
    ['id' => 4, 'name' => 'Apple', 'parent_id' => 2]
];

$tree = array_reduce($categories, function($carry, $item) {
    $carry[$item['parent_id']][] = $item;
    return $carry;
}, []);

print_r($tree);
?>
Пример 5: Композиция функций
Пример php
<?php
$functions = [
    function($x) { return $x * 2; },
    function($x) { return $x + 10; },
    function($x) { return $x / 3; }
];

$composed = array_reduce($functions, function($carry, $func) {
    return function($x) use ($carry, $func) {
        return $func($carry($x));
    };
}, function($x) { return $x; });

$result = $composed(5);
echo $result;
?>
6.6666666666667

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

JavaScript: reduce()
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, current) => accumulator + current, 0);
console.log(sum);
15

Метод reduce() массивов в JavaScript работает аналогично, но является методом объекта Array, а не отдельной функцией.

Python: functools.reduce()
from functools import reduce
numbers = [1, 2, 3, 4, 5]
sum_result = reduce(lambda x, y: x + y, numbers, 0)
print(sum_result)
15

В Python reduce() находится в модуле functools и требует импорта. Синтаксис похож, но Python использует lambda-функции для callback.

SQL: агрегатные функции
SELECT SUM(column_name) FROM table_name;
-- или с GROUP BY для группировки
SELECT category, SUM(value) FROM table GROUP BY category;

В SQL агрегатные функции (SUM, AVG, COUNT и др.) выполняют схожие операции, но на уровне базы данных.

PHP array_reduce function comments

En
Array reduce Iteratively reduce the array to a single value using a callback function