Desafio JavaScript
Relatório de produtos com formatação
Enunciado
Dado um array de objetos produtos (cada um com nome, preco e quantidade), crie uma função gerarRelatorio(produtos) que retorna uma string formatada em múltiplas linhas usando template literals. Cada linha deve seguir o formato:
[nome]: [quantidade] unidades - Total: R$ [preco * quantidade com 2 casas decimais]
No final, adicione uma linha com o valor total geral. Use métodos de string para deixar o nome em maiúsculas e remover espaços extras.
Requisitos
- Usar template literals com interpolação e múltiplas linhas.
- Usar
toUpperCase()etrim()nos nomes. - Calcular total por produto e total geral com
toFixed(2). - Retornar uma única string com quebras de linha (
\n).
Código inicial
function gerarRelatorio(produtos) {
// Seu código aqui
}
const produtos = [
{ nome: " caneta ", preco: 2.5, quantidade: 10 },
{ nome: "Lápis", preco: 1.2, quantidade: 5 },
{ nome: "borracha", preco: 3.0, quantidade: 2 }
];
console.log(gerarRelatorio(produtos));
Saída esperada
CANETA: 10 unidades - Total: R$ 25.00
LÁPIS: 5 unidades - Total: R$ 6.00
BORRACHA: 2 unidades - Total: R$ 6.00
Total geral: R$ 37.00
Ver dica
Use map para gerar as linhas e join('\n') para uni-las. Acumule o total geral em uma variável.
Mostrar solução
function gerarRelatorio(produtos) {
let totalGeral = 0;
const linhas = produtos.map(produto => {
const nome = produto.nome.trim().toUpperCase();
const total = produto.preco * produto.quantidade;
totalGeral += total;
return `${nome}: ${produto.quantidade} unidades - Total: R$ ${total.toFixed(2)}`;
});
linhas.push(`Total geral: R$ ${totalGeral.toFixed(2)}`);
return linhas.join('\n');
}
const produtos = [
{ nome: " caneta ", preco: 2.5, quantidade: 10 },
{ nome: "Lápis", preco: 1.2, quantidade: 5 },
{ nome: "borracha", preco: 3.0, quantidade: 2 }
];
console.log(gerarRelatorio(produtos));
Passo a passo
- Inicializamos
totalGeralcomo 0 para acumular o valor de todos os produtos. - Usamos
produtos.map()para iterar e criar um array de strings formatadas. - Para cada produto,
nome.trim().toUpperCase()limpa e padroniza o nome. - Calculamos
total = preco * quantidadee adicionamos atotalGeral. - O template literal monta a linha com os valores interpolados e
toFixed(2)formata o preço. - Após o
map, adicionamos a linha do total geral compush. join('\n')une todas as linhas em uma única string com quebras de linha.
Por que funciona
A imutabilidade das strings garante que trim() e toUpperCase() não alterem os nomes originais. O template literal permite interpolar expressões complexas e criar múltiplas linhas sem concatenação. O acúmulo do total geral é feito com uma variável externa ao map.
Erros comuns
- Esquecer de inicializar
totalGeralantes domap. - Usar
forEachem vez demape tentar retornar (forEach não retorna array). - Não usar
toFixed(2)e obter números com muitas casas decimais. - Modificar o array original com
sortoureversesem necessidade.
Outra forma de resolver
Usar reduce para acumular as linhas e o total:
const { linhas, total } = produtos.reduce((acc, p) => {
const nome = p.nome.trim().toUpperCase();
const totalProd = p.preco * p.quantidade;
acc.linhas.push(`${nome}: ${p.quantidade} unidades - Total: R$ ${totalProd.toFixed(2)}`);
acc.total += totalProd;
return acc;
}, { linhas: [], total: 0 });
linhas.push(`Total geral: R$ ${total.toFixed(2)}`);
return linhas.join('\n');
Mas a versão com map é mais simples.
Saída esperada
CANETA: 10 unidades - Total: R$ 25.00
LÁPIS: 5 unidades - Total: R$ 6.00
BORRACHA: 2 unidades - Total: R$ 6.00
Total geral: R$ 37.00