Como usar map, filter e reduce no PHP

Como usar map, filter e reduce no PHP

No artigo anterior, eu falei sobre o uso de arrow functions dentro do PHP. Você pode lê-lo neste link.

Hoje, seguindo com a aplicação de conceitos funcionais no PHP, vamos falar sobre 3 funções amplamente utlizadas quando precisamos percorrer um array e, se fossemos usar um loop tradicional, teríamos um pouco mais de trabalho. Estou falando do array_map, array_filter e o array_reduce.

Para começar, vamos usar um array que será aplicado em todos os exemplos deste artigo. Um array com os Top 3 filmes que mais arrecadaram na história do cinema. Vamos ter o título do filme, nota no IMDB, faturamento nos Estados Unidos, e faturamento no Brasil.

    $filmes = [
        [
            'titulo' => 'Vingadores: Ultimato',
            'imdb' => 8.4,
            'faturamento_us' => 858300000,
            'faturamento_br' => 85660000
        ],
        [
            'titulo' => 'Avatar',
            'imdb' => 7.8,
            'faturamento_us' => 760500000,
            'faturamento_br' => 58210000
        ],
        [
            'titulo' => 'Titanic',
            'imdb' => 7.8,
            'faturamento_us' => 659360000,
            'faturamento_br' => 70460000
        ],
    ];

array_map

A função array_map tem como objetivo percorrer todo o array e mapear cada um dos itens processando-os com o que é pedido, e gerando um novo array com os novos valores.

No nosso exemplo, vamos supor que o valor total das arrecadações são valores brutos, e que nós vamos descontar os impostos para mostrar o valor líquido. Vamos usar os valores fictícios de 16% para o Brasil e 6% para os Estados Unidos.

    $filmesDepoisDosImpostos = array_map(function ($filme) {
        $filme['faturamento_us'] -= $filme['faturamento_us'] * 0.06;
        $filme['faturamento_br'] -= $filme['faturamento_br'] * 0.16;
        return $filme;
    }, $filmes);

    var_dump($filmesDepoisDosImpostos);

Você pode perceber que a função array_map recebe 2 parâmetros: o primeiro é a função onde o mapeamento é feito, e o segundo é o array que irá fornecer os dados para serem mapeados.

array_filter

A função array_filter tem como objetivo filtrar os itens do array que atendam a uma condição estipulada dentro da função, e gerando um novo array apenas com os itens filtrados.

Por exemplo, eu quero filtrar pelos filmes que tenham a nota no IMDB abaixo de 8.

    $filmesNotaMenorQueOito = array_filter($filmes, function ($filme) {
        return $filme['imdb'] < 8;
    });

    var_dump($filmesNotaMenorQueOito);

Nesse caso aqui, os parâmetros se invertem em relação ao array_map. O primeiro parâmetro é o array que servirá como base para a filtragem, e o segundo é a função que irá estipular a condição para o filtro.

Se você reparar na saída do código, o novo array manteve a chave original dos itens do array original. Isso pode facilitar se você quiser chamar o array original usando as mesmas chaves.

array_reduce

A função array_reduce tem como objetivo reduzir o array a um único valor utilizando alguma operação aritmética para tal.

Neste exemplo, eu quero somar o faturamento no Brasil dos 3 filmes.

    $totalFaturamentoBR = array_reduce($filmes, function ($total, $filme) {
        $total += $filme['faturamento_br'];
        return $total;
    }, 0);

    var_dump($totalFaturamentoBR);

Aqui, temos 3 parâmetros. O primeiro é o array original que servirá como base para a operação aritmética, o segundo é a função que irá processar o cálculo, e o terceiro (opcional) servirá como valor inicial da operação. No nosso caso, como ele está 0(zero) não faria diferença se nós o removessemos. Mas vamos supor que além desse faturamento, fossemos adicionar o valor arrecadado desses mesmos filmes com streaming. Colocariamos esse valor no terceiro parâmetro.

Achou fácil? Espero que eu tenha ajudado a elucidar suas dúvidas.


Para finalizar, gostaria de refazer 2 dos exemplos acima utilizando maneiras de deixar o código mais legível e clean.

Função externa

O primeiro exemplo será com o array_map e será usando uma função que foi declarada fora do seu escopo.

    function aplicarImposto($filme) {
        $filme['faturamento_us'] -= $filme['faturamento_us'] * 0.06;
        $filme['faturamento_br'] -= $filme['faturamento_br'] * 0.16;
        return $filme;
    }

    $filmesDepoisDosImpostos = array_map("aplicarImposto", $filmes);

    var_dump($filmesDepoisDosImpostos);

Criamos a função aplicarImposto com o mesmo formato e conteúdo da versão anterior. Dentro do array_map, chamamos a função como uma string, e o parâmetro é passado de forma implícita. Visualmente, fica mais fácil de entender o código, mas tudo é questão de costume.

Arrow function

No artigo anterior falei sobre arrow function. A boa notícia é que podemos usá-la em conjunto com essas funções (quando o contexto permite, é claro). Lembrando que arrow function só irá funcionar a partir da versão 7.4 da linguagem.

    $filmesNotaMenorQueOito = array_filter($filmes, fn($filme) => $filme['imdb'] < 8);

    var_dump($filmesNotaMenorQueOito);

Conseguimos reduzir a 1 linha o exemplo anterior do array_filter.


E aí, o que achou? Espero que tenha gostado.

É sempre bom lembrar, dúvidas e feedbacks são sempre muito bem vindos.