Função array_reduce() do PHP: O Guia Completo
Aprenda a usar a função array_reduce() do PHP para processar arrays e transformá-los em um único valor com exemplos práticos.
array_reduce() percorre um array elemento por elemento e o reduz a um único valor — uma soma, uma contagem, o maior item, uma estrutura reconstruída, entre outros. A cada iteração, passa duas coisas ao seu callback: o resultado acumulado até agora (o acumulador, convencionalmente chamado de $carry) e o elemento atual ($item). O que o callback retornar torna-se o novo acumulador para a próxima iteração, e o acumulador final é o que array_reduce() retorna.
Use-a sempre que precisar reduzir um array inteiro a um único resultado e uma chamada simples a array_sum(), array_filter() ou array_map() não for suficiente — por exemplo, somar apenas certos elementos, construir uma tabela de pesquisa ou encontrar um máximo com lógica personalizada. Este guia abrange a sintaxe, o fluxo do acumulador, padrões comuns e as armadilhas mais frequentes.
Sintaxe
array_reduce(array $array, callable $callback, mixed $initial = null): mixed| Parâmetro | Descrição |
|---|---|
$array | O array de entrada a ser reduzido. |
$callback | Função chamada uma vez por elemento. Recebe ($carry, $item) e deve retornar o novo acumulador. |
$initial | Valor inicial opcional para $carry. Padrão é null. |
A assinatura do callback é:
function (mixed $carry, mixed $item): mixed$carrycontém o resultado acumulado até agora —$initialna primeira chamada.$itemé o elemento atual do array.- O valor de retorno torna-se
$carrypara o próximo elemento. Esquecer de retornar é o bug mais comum.
array_reduce() ignora as chaves do array; apenas os valores são passados ao callback. Se precisar das chaves, itere manualmente ou use array_keys() primeiro.
Casos de uso comuns
array_reduce() se destaca sempre que muitos valores precisam se tornar um. Os padrões comuns incluem:
- Somar ou multiplicar elementos
- Contar elementos que satisfazem uma condição
- Construir um array associativo (tabela de pesquisa) a partir de uma lista
- Achatar ou mesclar arrays aninhados
- Encontrar um mínimo ou máximo com lógica de comparação personalizada
Exemplo 1: Somando Elementos de um Array
O uso mais simples é somar números. O callback adiciona o elemento atual ao total acumulado, e o 0 passado como $initial faz o total começar em zero.
$carry mantém o total acumulado, começando em 0, e $item é o número atual. Para uma soma simples como esta, você também poderia usar o built-in array_sum() — array_reduce() se torna útil quando o acúmulo precisa de lógica personalizada (somar apenas números pares, multiplicar, etc.).
Exemplo 2: Contando Elementos de um Array
Você pode contar elementos incrementando o acumulador a cada iteração em vez de adicionar o valor do elemento. Note como $item é intencionalmente não utilizado aqui — array_reduce() não obriga o uso do elemento atual.
Neste exemplo, a variável $carry mantém o controle da contagem, começando em 0. A variável $item contém o elemento atual sendo processado, mas não é usada neste caso.
Exemplo 3: Construindo um Array Associativo (Tabela de Pesquisa)
Um padrão muito prático é transformar uma lista de registros em uma pesquisa indexada por chave, para que você possa encontrar uma entrada pelo nome em vez de percorrer toda a lista. O acumulador começa como um array vazio e ganha uma chave por registro.
<?php
$data = array(
array("name" => "John", "age" => 25),
array("name" => "Jane", "age" => 30),
array("name" => "Jim", "age" => 35)
);
$people = array_reduce($data, function($carry, $item) {
$carry[$item["name"]] = $item["age"];
return $carry;
}, array());
print_r($people);
?>O resultado é Array ( [John] => 25 [Jane] => 30 [Jim] => 35 ). Cada $item é um registro de pessoa; o callback usa o nome da pessoa como chave e sua idade como valor, retornando o array atualizado para que a próxima iteração possa adicionar a ele.
Exemplo 4: Achatando Arrays Aninhados
Você pode achatar um array de arrays em um único array plano mesclando cada sub-array no acumulador. Como array_merge() retorna um novo array, retornar seu resultado mantém $carry crescendo corretamente.
Aqui a entrada é [[1, 2], [3, 4], [5]]. Cada $item é um array interno, e array_merge() acrescenta seus valores a $carry, produzindo uma única lista plana. (Isso achata apenas um nível de profundidade.)
Exemplo 5: Mesclando Vários Arrays em Um
A mesma ideia de mesclagem funciona para combinar uma coleção de arrays separados. Envolva os arrays que deseja unir em um array externo e mescle cada um no acumulador.
$colors e $fruits são mesclados em ordem, resultando em um array combinado. Com muitos arrays, isso é mais limpo do que encadear várias chamadas a array_merge() manualmente.
Usando arrow functions
Desde o PHP 7.4, você pode escrever o callback como uma arrow function concisa. Ela captura variáveis externas automaticamente e retorna sua expressão implicitamente, eliminando o return fácil de esquecer:
<?php
$numbers = [1, 2, 3, 4, 5];
$sum = array_reduce($numbers, fn($carry, $item) => $carry + $item, 0);
echo $sum; // 15
?>Armadilhas comuns
- Sempre retorne do callback. Se um caminho de código esquecer de
return $carry, o acumulador torna-senulle tudo depois quebra. Arrow functions evitam esse problema. - Atenção ao valor inicial. Sem
$initial,$carrycomeça comonull. Para somas numéricas passe0; para construção de arrays passe[]. Caso contrário, o primeiroarray_merge(null, …)ounull + 1se comportará incorretamente ou gerará avisos. - Arrays vazios retornam o valor inicial.
array_reduce([], $fn, 0)retorna0; sem valor inicial, retornanull. Trate esse caso se uma entrada vazia for possível. - Chaves são ignoradas. Apenas os valores chegam ao callback. Reduza sobre
array_keys($arr)se precisar delas.
Este exemplo encontra o máximo sem um valor inicial, tratando o primeiro elemento de forma especial:
<?php
$numbers = [10, 5, 20, 8];
$max = array_reduce($numbers, function ($carry, $item) {
return ($carry === null || $item > $carry) ? $item : $carry;
});
echo $max; // 20
?>Funções relacionadas
array_map()— transforma cada elemento em um novo array (um para um), em vez de reduzir a um único valor.array_filter()— mantém apenas os elementos que passam em um teste.array_sum()— um atalho para o caso simples de soma.array_merge()— une arrays diretamente quando nenhuma lógica por elemento é necessária.
Conclusão
array_reduce() reduz um array a um único valor encadeando um acumulador por um callback. Depois que você internalizar o fluxo ($carry, $item) => newCarry, poderá somar, contar, construir tabelas de pesquisa, achatar e mesclar com a mesma ferramenta compacta. Lembre-se das duas regras que previnem a maioria dos bugs: sempre retorne o novo acumulador e escolha um valor $initial que corresponda ao tipo que você está construindo.