Dominando a Busca, Filtragem e Transformação de Dados
Você já aprendeu a criar arrays e manipulá-los com métodos básicos como push, pop, shift e unshift. Agora é hora de dar o próximo passo! Nesta aula, você descobrirá métodos poderosos que transformarão a maneira como você trabalha com listas de dados.
Imagine ter uma lista com centenas de produtos e precisar encontrar apenas aqueles que custam menos de R$ 100. Ou transformar uma lista de nomes para que todos fiquem em letras maiúsculas. Os métodos que aprenderemos hoje tornam essas tarefas simples e elegantes!
Buscando Elementos: includes(), indexOf() e find()
1.1 O Método includes()
O includes() é o método mais simples para verificar se um elemento existe no array. Ele retorna true se o elemento for encontrado e false caso contrário.
Sintaxe:
array.includes(elemento)
Exemplo Prático:
let frutas = ["maçã", "banana", "uva", "laranja"];
console.log(frutas.includes("banana")); // true
console.log(frutas.includes("morango")); // false
Quando usar: Sempre que você precisar apenas saber SE um elemento existe, sem se importar com sua posição.
Caso Real:
let produtosNoCarrinho = ["notebook", "mouse", "teclado"];
if (produtosNoCarrinho.includes("mouse")) {
console.log("O mouse já está no carrinho!");
} else {
console.log("Adicione o mouse ao carrinho.");
}
1.2 O Método indexOf()
Enquanto o includes() apenas verifica existência, o indexOf() nos diz ONDE o elemento está. Ele retorna o índice (posição) do primeiro elemento encontrado, ou -1 se não encontrar nada.
Sintaxe:
array.indexOf(elemento)
Por que retorna -1? Esta é uma convenção clássica em programação para indicar "não encontrado", já que índices válidos começam em 0.
Exemplo Prático:
let animais = ["gato", "cachorro", "pássaro", "cachorro"];
console.log(animais.indexOf("cachorro")); // 1 (primeira ocorrência)
console.log(animais.indexOf("peixe")); // -1 (não encontrado)
Diferença importante: O indexOf() retorna apenas a posição da PRIMEIRA ocorrência.
Caso Real:
let tarefas = ["estudar", "exercitar", "ler", "programar"];
let posicao = tarefas.indexOf("exercitar");
if (posicao !== -1) {
console.log(`A tarefa está na posição ${posicao}`);
tarefas[posicao] = "exercitar ✓"; // Marcar como concluída
}
1.3 O Método find()
O find() é o mais poderoso dos três. Ele procura o primeiro elemento que satisfaz uma condição (não apenas igualdade exata). Retorna o elemento encontrado ou undefined se nenhum satisfizer a condição.
Sintaxe:
array.find(funcao)
Exemplo Prático:
let numeros = [5, 12, 8, 130, 44];
// Encontrar o primeiro número maior que 10
let resultado = numeros.find(numero => numero > 10);
console.log(resultado); // 12
Buscando em Arrays de Objetos:
let usuarios = [
{id: 1, nome: "Ana", idade: 25},
{id: 2, nome: "Bruno", idade: 30},
{id: 3, nome: "Carla", idade: 22}
];
// Encontrar usuário com id específico
let usuario = usuarios.find(u => u.id === 2);
console.log(usuario.nome); // "Bruno"
// Encontrar primeiro usuário maior de idade
let adulto = usuarios.find(u => u.idade >= 18);
console.log(adulto.nome); // "Ana"
Quando usar: Quando você precisa buscar baseado em uma condição mais complexa que simples igualdade.
Filtrando Dados: O Método filter()
2.1 Conceito Fundamental
Enquanto o find() retorna apenas o PRIMEIRO elemento que satisfaz a condição, o filter() retorna TODOS os elementos que atendem ao critério. Ele cria um novo array com os elementos filtrados.
Princípio: Filtrar significa "separar o que queremos do que não queremos".
Sintaxe:
array.filter(funcao)
2.2 Exemplos Práticos
Filtrando Números:
let numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Apenas números pares
let pares = numeros.filter(n => n % 2 === 0);
console.log(pares); // [2, 4, 6, 8, 10]
// Números maiores que 5
let maioresQue5 = numeros.filter(n => n > 5);
console.log(maioresQue5); // [6, 7, 8, 9, 10]
Filtrando Objetos:
let produtos = [
{nome: "Notebook", preco: 3000, categoria: "eletrônicos"},
{nome: "Mouse", preco: 50, categoria: "eletrônicos"},
{nome: "Livro", preco: 40, categoria: "livros"},
{nome: "Teclado", preco: 150, categoria: "eletrônicos"}
];
// Produtos baratos (menos de R$ 100)
let baratos = produtos.filter(p => p.preco < 100);
console.log(baratos);
// [{nome: "Mouse"...}, {nome: "Livro"...}]
// Apenas eletrônicos
let eletronicos = produtos.filter(p => p.categoria === "eletrônicos");
console.log(eletronicos.length); // 3
Filtrando Strings:
let palavras = ["JavaScript", "Python", "Java", "Ruby", "PHP"];
// Palavras com mais de 4 letras
let longas = palavras.filter(palavra => palavra.length > 4);
console.log(longas); // ["JavaScript", "Python"]
// Palavras que contêm "Java"
let comJava = palavras.filter(palavra => palavra.includes("Java"));
console.log(comJava); // ["JavaScript", "Java"]
2.3 Características Importantes
- Não modifica o array original - Sempre retorna um novo array
- Pode retornar array vazio - Se nenhum elemento satisfizer a condição
- Mantém a ordem - Os elementos filtrados aparecem na mesma ordem do array original
let idades = [15, 22, 18, 30, 12, 25];
let maioresDeIdade = idades.filter(idade => idade >= 18);
console.log(idades); // [15, 22, 18, 30, 12, 25] - não mudou
console.log(maioresDeIdade); // [22, 18, 30, 25] - novo array
Transformando Dados: O Método map()
3.1 Conceito de Transformação
O map() é um dos métodos mais poderosos e utilizados. Ele aplica uma função a CADA elemento do array e retorna um NOVO array com os resultados transformados.
Princípio: Transformar significa "pegar cada elemento e convertê-lo em algo novo".
Sintaxe:
array.map(funcao)
3.2 Exemplos Práticos
Transformando Números:
let numeros = [1, 2, 3, 4, 5];
// Dobrar cada número
let dobrados = numeros.map(n => n * 2);
console.log(dobrados); // [2, 4, 6, 8, 10]
// Elevar ao quadrado
let quadrados = numeros.map(n => n * n);
console.log(quadrados); // [1, 4, 9, 16, 25]
// Converter para strings
let strings = numeros.map(n => `Número ${n}`);
console.log(strings); // ["Número 1", "Número 2", ...]
Transformando Objetos:
let pessoas = [
{nome: "Ana", idade: 25},
{nome: "Bruno", idade: 30},
{nome: "Carla", idade: 22}
];
// Extrair apenas os nomes
let nomes = pessoas.map(pessoa => pessoa.nome);
console.log(nomes); // ["Ana", "Bruno", "Carla"]
// Criar saudações personalizadas
let saudacoes = pessoas.map(pessoa => `Olá, ${pessoa.nome}!`);
console.log(saudacoes);
// ["Olá, Ana!", "Olá, Bruno!", "Olá, Carla!"]
// Adicionar nova propriedade
let pessoasComCategoria = pessoas.map(pessoa => ({
...pessoa,
categoria: pessoa.idade >= 25 ? "adulto" : "jovem"
}));
console.log(pessoasComCategoria);
Transformando Strings:
let nomes = ["ana", "bruno", "carla"];
// Primeira letra maiúscula
let capitalizados = nomes.map(nome =>
nome.charAt(0).toUpperCase() + nome.slice(1)
);
console.log(capitalizados); // ["Ana", "Bruno", "Carla"]
3.3 Características Importantes
- Sempre retorna array do mesmo tamanho - Se entrar 5 elementos, sai 5 elementos
- Não modifica o array original
- Pode transformar tipos - Entrar números, sair strings
let precos = [10, 20, 30];
// Array original não muda
let precosComDesconto = precos.map(p => p * 0.9);
console.log(precos); // [10, 20, 30]
console.log(precosComDesconto); // [9, 18, 27]
Verificação: some() e every()
4.1 O Método some()
O some() verifica se PELO MENOS UM elemento satisfaz a condição. Retorna true ou false.
Sintaxe:
array.some(funcao)
Exemplos:
let numeros = [1, 3, 5, 8, 9];
// Existe algum número par?
console.log(numeros.some(n => n % 2 === 0)); // true (8 é par)
// Existe algum número negativo?
console.log(numeros.some(n => n < 0)); // false
let produtos = [
{nome: "Mouse", preco: 50},
{nome: "Teclado", preco: 150},
{nome: "Monitor", preco: 800}
];
// Existe algum produto barato (menos de R$ 100)?
console.log(produtos.some(p => p.preco < 100)); // true
4.2 O Método every()
O every() verifica se TODOS os elementos satisfazem a condição. Retorna true ou false.
Sintaxe:
array.every(funcao)
Exemplos:
let idades = [20, 25, 30, 35];
// Todos são maiores de idade?
console.log(idades.every(idade => idade >= 18)); // true
// Todos são maiores de 25?
console.log(idades.every(idade => idade > 25)); // false
let notas = [7, 8, 6, 9];
// Todos foram aprovados (nota >= 6)?
console.log(notas.every(nota => nota >= 6)); // true
4.3 Diferença Conceitual
- some(): "Existe PELO MENOS UM?"
- every(): "São TODOS?"
let numeros = [2, 4, 6, 8, 10];
console.log(numeros.some(n => n > 5)); // true (existe algum)
console.log(numeros.every(n => n > 5)); // false (não são todos)
console.log(numeros.some(n => n % 2 === 0)); // true
console.log(numeros.every(n => n % 2 === 0)); // true (todos são pares)
Ordenação: O Método sort()
5.1 Ordenação Básica
O sort() ordena os elementos do array. ATENÇÃO: Ele modifica o array original!
Sintaxe:
array.sort()
array.sort(funcaoDeComparacao)
5.2 O Problema da Ordenação Padrão
Por padrão, o sort() converte elementos para strings e compara lexicograficamente (como em um dicionário). Isso causa resultados inesperados com números!
let numeros = [10, 5, 40, 25, 1000, 1];
// Ordenação padrão (ERRADA para números!)
numeros.sort();
console.log(numeros); // [1, 10, 1000, 25, 40, 5] 😱
// Ordena como texto: "1" < "10" < "1000" < "25"...
5.3 Ordenação Numérica Correta
Para ordenar números, precisamos fornecer uma função de comparação:
let numeros = [10, 5, 40, 25, 1000, 1];
// Ordem crescente
numeros.sort((a, b) => a - b);
console.log(numeros); // [1, 5, 10, 25, 40, 1000] ✓
// Ordem decrescente
numeros.sort((a, b) => b - a);
console.log(numeros); // [1000, 40, 25, 10, 5, 1] ✓
Como funciona:
- Se
a - bfor negativo,avem antes deb - Se
a - bfor positivo,bvem antes dea - Se for zero, mantém a ordem
5.4 Ordenando Strings
Para strings, a ordenação padrão funciona bem:
let frutas = ["banana", "maçã", "uva", "abacaxi"];
frutas.sort();
console.log(frutas); // ["abacaxi", "banana", "maçã", "uva"]
// Ordem inversa
frutas.sort().reverse();
console.log(frutas); // ["uva", "maçã", "banana", "abacaxi"]
5.5 Ordenando Objetos
let produtos = [
{nome: "Mouse", preco: 50},
{nome: "Teclado", preco: 150},
{nome: "Monitor", preco: 800}
];
// Ordenar por preço (crescente)
produtos.sort((a, b) => a.preco - b.preco);
console.log(produtos);
// Ordenar por nome (alfabética)
produtos.sort((a, b) => a.nome.localeCompare(b.nome));
console.log(produtos);
Combinando Métodos (Encadeamento)
Uma das características mais poderosas é a possibilidade de encadear métodos, aplicando múltiplas operações em sequência!
6.1 Exemplos de Encadeamento
let numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Filtrar pares, dobrar valores, somar tudo
let resultado = numeros
.filter(n => n % 2 === 0) // [2, 4, 6, 8, 10]
.map(n => n * 2); // [4, 8, 12, 16, 20]
console.log(resultado);
Exemplo Real - Sistema de Produtos:
let produtos = [
{nome: "Notebook", preco: 3000, estoque: 5},
{nome: "Mouse", preco: 50, estoque: 0},
{nome: "Teclado", preco: 150, estoque: 10},
{nome: "Monitor", preco: 800, estoque: 3}
];
// Encontrar produtos disponíveis, ordenar por preço e formatar
let produtosFormatados = produtos
.filter(p => p.estoque > 0) // Apenas disponíveis
.sort((a, b) => a.preco - b.preco) // Ordenar por preço
.map(p => `${p.nome}: R$ ${p.preco}`); // Formatar
console.log(produtosFormatados);
// ["Mouse: R$ 50", "Teclado: R$ 150", "Monitor: R$ 800", "Notebook: R$ 3000"]
Casos de Uso Práticos
7.1 Sistema de Busca de Produtos
let produtos = [
{id: 1, nome: "Notebook Dell", preco: 3000, categoria: "eletrônicos"},
{id: 2, nome: "Mouse Logitech", preco: 50, categoria: "eletrônicos"},
{id: 3, nome: "Livro JavaScript", preco: 40, categoria: "livros"},
{id: 4, nome: "Teclado Mecânico", preco: 300, categoria: "eletrônicos"}
];
function buscarProdutos(termo, precoMaximo) {
return produtos
.filter(p => p.nome.toLowerCase().includes(termo.toLowerCase()))
.filter(p => p.preco <= precoMaximo)
.sort((a, b) => a.preco - b.preco);
}
console.log(buscarProdutos("mouse", 100));
// [{id: 2, nome: "Mouse Logitech", preco: 50, ...}]
7.2 Análise de Notas de Alunos
let alunos = [
{nome: "Ana", nota: 8.5},
{nome: "Bruno", nota: 6.0},
{nome: "Carla", nota: 9.0},
{nome: "Diego", nota: 5.5},
{nome: "Elena", nota: 7.5}
];
// Alunos aprovados (nota >= 6)
let aprovados = alunos.filter(a => a.nota >= 6);
console.log(`${aprovados.length} alunos aprovados`);
// Todos foram aprovados?
let todosAprovados = alunos.every(a => a.nota >= 6);
console.log(`Todos aprovados: ${todosAprovados}`);
// Alguém tirou nota máxima?
let temNotaMaxima = alunos.some(a => a.nota === 10);
console.log(`Tem nota 10: ${temNotaMaxima}`);
// Nomes dos aprovados em ordem alfabética
let nomesAprovados = alunos
.filter(a => a.nota >= 6)
.map(a => a.nome)
.sort();
console.log(nomesAprovados);
7.3 Processamento de Dados de Vendas
let vendas = [
{produto: "Mouse", quantidade: 5, precoUnitario: 50},
{produto: "Teclado", quantidade: 3, precoUnitario: 150},
{produto: "Monitor", quantidade: 2, precoUnitario: 800}
];
// Calcular valor total de cada venda
let vendasComTotal = vendas.map(v => ({
...v,
total: v.quantidade * v.precoUnitario
}));
console.log(vendasComTotal);
// Vendas acima de R$ 400
let vendasGrandes = vendasComTotal.filter(v => v.total > 400);
console.log(vendasGrandes);
Comparação entre Métodos
| Método | Retorna | Modifica Original? | Quando Usar |
|--------|---------|-------------------|-------------|
| includes() | Boolean | Não | Verificar se elemento existe |
| indexOf() | Number (índice) | Não | Encontrar posição de elemento |
| find() | Elemento ou undefined | Não | Buscar primeiro elemento que atende condição |
| filter() | Array | Não | Obter todos os elementos que atendem condição |
| map() | Array | Não | Transformar todos os elementos |
| some() | Boolean | Não | Verificar se ALGUM elemento atende condição |
| every() | Boolean | Não | Verificar se TODOS os elementos atendem condição |
| sort() | Array | SIM | Ordenar elementos |
Conceitos Importantes para Fixar
9.1 Imutabilidade
A maioria desses métodos não modifica o array original. Eles criam e retornam um novo array:
let original = [1, 2, 3];
let dobrado = original.map(n => n * 2);
console.log(original); // [1, 2, 3] - não mudou!
console.log(dobrado); // [2, 4, 6]
Exceção: O sort() modifica o array original!
9.2 Funções de Callback
Todos esses métodos recebem uma função como argumento. Essa função é chamada para cada elemento do array:
array.map(function(elemento, indice, arrayCompleto) {
// Esta função é executada para cada elemento
return elemento; // Retorna o valor transformado
});
// Forma mais comum com arrow function
array.map(elemento => elemento * 2);
9.3 Programação Funcional
Esses métodos representam um paradigma de programação chamado programação funcional, onde:
- Trabalhamos com transformações de dados
- Evitamos modificar dados existentes
- Componemos operações simples para criar soluções complexas
Próximos Passos
Na próxima aula nos aprofundaremos nos objetos. Você vai aprender:
- Novas formas de criar e acessar propriedades de objetos
- Como alterar, adicionar e deletar propriedades
- Percorrer todas as propriedades dde um objeto
- Criar objetos dentro de objetos
Lembre-se: A prática leva à perfeição. Quanto mais você usar esses métodos, mais natural se tornará identificar qual usar em cada situação!