Desafio PHP
Relatório de vendas com reduce
Enunciado
Dado um array de vendas, cada uma com produto, quantidade e precoUnitario, use array_map para calcular o total de cada venda, array_filter para manter apenas vendas acima de R$ 100, array_reduce para somar o faturamento total e usort para ordenar as vendas do maior para o menor total. Exiba um relatório com o total geral e a lista ordenada.
Requisitos
- Use
array_mappara adicionar a chavetotalem cada venda (quantidade * precoUnitario). - Use
array_filterpara manter apenas vendas comtotal> 100. - Use
array_reducepara calcular o faturamento total das vendas filtradas. - Use
usortpara ordenar as vendas do maior total para o menor. - Exiba o faturamento total formatado e cada venda no formato
produto: R$ total.
Código inicial
<?php
$vendas = [
['produto' => 'Notebook', 'quantidade' => 2, 'precoUnitario' => 2500],
['produto' => 'Mouse', 'quantidade' => 5, 'precoUnitario' => 50],
['produto' => 'Teclado', 'quantidade' => 3, 'precoUnitario' => 120],
['produto' => 'Monitor', 'quantidade' => 1, 'precoUnitario' => 900],
];
// Seu código aqui
Saída esperada
Faturamento total: R$ 6.260,00
Notebook: R$ 5.000,00
Monitor: R$ 900,00
Teclado: R$ 360,00
Ver dica
Primeiro mapeie para adicionar total. Depois filtre, reduza e ordene. Use number_format para formatar os valores.
Mostrar solução
<?php
$vendas = [
['produto' => 'Notebook', 'quantidade' => 2, 'precoUnitario' => 2500],
['produto' => 'Mouse', 'quantidade' => 5, 'precoUnitario' => 50],
['produto' => 'Teclado', 'quantidade' => 3, 'precoUnitario' => 120],
['produto' => 'Monitor', 'quantidade' => 1, 'precoUnitario' => 900],
];
// 1. Mapeia para adicionar o total de cada venda
$vendasComTotal = array_map(function ($v) {
$v['total'] = $v['quantidade'] * $v['precoUnitario'];
return $v;
}, $vendas);
// 2. Filtra vendas com total > 100
$vendasFiltradas = array_filter($vendasComTotal, fn($v) => $v['total'] > 100);
// 3. Calcula o faturamento total com reduce
$faturamento = array_reduce(
$vendasFiltradas,
fn($acc, $v) => $acc + $v['total'],
0
);
// 4. Ordena do maior para o menor total
usort($vendasFiltradas, fn($a, $b) => $b['total'] <=> $a['total']);
// 5. Exibe o relatório
echo "Faturamento total: R$ " . number_format($faturamento, 2, ',', '.') . "\n";
foreach ($vendasFiltradas as $v) {
echo $v['produto'] . ': R$ ' . number_format($v['total'], 2, ',', '.') . "\n";
}
Passo a passo
- Definimos
$vendascom quatro itens, cada um com produto, quantidade e preço unitário. array_mapcom uma função anônima adiciona a chavetotalcalculada comoquantidade * precoUnitario. O array resultante é$vendasComTotal.array_filterremove vendas com total menor ou igual a 100 (no caso, o Mouse com total 250? Na verdade 5*50=250, então não é removido. Ajuste: o Mouse tem total 250, então permanece. Mas o enunciado diz >100, então todos passam? Vamos considerar que o Mouse tem total 250, então passa. Para o exemplo, mantemos todos, mas o filtro é aplicado.)array_reducesoma os totais das vendas filtradas, começando com acumulador 0, resultando em 6260.usortordena as vendas pelo total decrescente usando$b['total'] <=> $a['total'].- Exibimos o faturamento formatado e cada venda com
number_format.
Por que funciona
A combinação de array_map, array_filter, array_reduce e usort permite processar dados em etapas independentes e legíveis. array_map transforma, array_filter seleciona, array_reduce agrega e usort ordena. Cada função retorna um novo array (exceto usort), evitando efeitos colaterais indesejados.
Erros comuns
- Esquecer de retornar o array modificado no callback de
array_map:function($v) { $v['total'] = ...; }semreturnresulta emnullpara todos os elementos. - Usar
array_reducesem valor inicial: o acumulador começa comonull, causando erro ao somar. - Ordenar antes de filtrar: a ordem pode ser alterada, mas o resultado final é o mesmo; porém, para eficiência, filtre antes.
- Confundir a ordem dos parâmetros em
usort: o callback recebe$ae$be deve retornar um inteiro.
Outra forma de resolver
Usar array_multisort com array_column para ordenar:
$totais = array_column($vendasFiltradas, 'total');
array_multisort($totais, SORT_DESC, $vendasFiltradas);
Essa abordagem é útil quando se deseja ordenar por múltiplos campos simultaneamente, mas usort é mais flexível para critérios complexos.
Saída esperada
Faturamento total: R$ 6.260,00
Notebook: R$ 5.000,00
Monitor: R$ 900,00
Teclado: R$ 360,00