Nesta aula, vamos explorar métodos avançados de iteração em arrays que vão além do tradicional loop for. Esses métodos tornam o código mais expressivo, funcional e fácil de ler. Dominar forEach, some, every, find, findIndex e sort é essencial para escrever JavaScript moderno e eficiente.

Vamos aprender como cada um funciona, suas particularidades e como evitar armadilhas, especialmente com sort, que pode se comportar de forma inesperada se não for usado corretamente.

forEach

O método forEach executa uma função callback para cada elemento do array, em ordem. É uma alternativa mais limpa ao for clássico quando você precisa apenas percorrer os elementos sem a necessidade de interromper o loop ou retornar um valor.

A função callback recebe até três argumentos: o valor atual, o índice e o array original. O forEach sempre retorna undefined, então não é encadeável para transformações.

const numeros = [1, 2, 3, 4, 5];

numeros.forEach((valor, indice, array) => {
  console.log(`Índice ${indice}: ${valor}`);
});
// Saída:
// Índice 0: 1
// Índice 1: 2
// Índice 2: 3
// Índice 3: 4
// Índice 4: 5

Uma observação importante: forEach não espera promessas. Se você usar async/await dentro do callback, as promessas serão executadas em paralelo, não em sequência. Para iteração assíncrona, prefira for...of ou Promise.all.

some/every

some testa se pelo menos um elemento do array satisfaz a condição fornecida pela função callback. Retorna true assim que encontra um elemento que atende à condição, interrompendo a iteração. every testa se todos os elementos satisfazem a condição; retorna false assim que encontra um elemento que não atende.

Ambos são úteis para validações e verificações rápidas. A função callback recebe os mesmos três argumentos: valor, índice e array.

const idades = [12, 18, 25, 30];

// Algum é maior de idade?
const temMaior = idades.some(idade => idade >= 18);
console.log(temMaior); // true

// Todos são maiores de idade?
const todosMaiores = idades.every(idade => idade >= 18);
console.log(todosMaiores); // false (12 é menor)

Esses métodos são especialmente úteis em conjunto com condições complexas e podem substituir loops com variáveis de controle.

find/findIndex

find retorna o primeiro elemento que satisfaz a condição fornecida. Se nenhum elemento atender, retorna undefined. findIndex retorna o índice do primeiro elemento que satisfaz a condição, ou -1 se não encontrar.

Diferentemente de filter, que retorna todos os elementos que atendem, find para na primeira ocorrência, sendo mais eficiente quando você espera apenas um resultado.

const usuarios = [
  { id: 1, nome: 'Ana' },
  { id: 2, nome: 'Bruno' },
  { id: 3, nome: 'Carla' }
];

const usuario = usuarios.find(u => u.id === 2);
console.log(usuario); // { id: 2, nome: 'Bruno' }

const indice = usuarios.findIndex(u => u.id === 3);
console.log(indice); // 2

É comum usar find para buscar objetos em arrays por uma propriedade única, como ID.

sort e suas pegadinhas

O método sort ordena os elementos do array in-place (modifica o array original) e retorna o array ordenado. Por padrão, sort converte os elementos para string e os compara lexicograficamente (sequência de caracteres Unicode). Isso causa comportamentos inesperados com números.

const numeros = [10, 5, 80, 2, 7];
numeros.sort();
console.log(numeros); // [10, 2, 5, 7, 80] - ordenação lexicográfica!

Para ordenar numericamente, é necessário fornecer uma função de comparação. A função recebe dois elementos (a, b) e deve retornar um número negativo se a deve vir antes de b, positivo se a deve vir depois, ou zero se são equivalentes.

numeros.sort((a, b) => a - b);
console.log(numeros); // [2, 5, 7, 10, 80] - crescente

numeros.sort((a, b) => b - a);
console.log(numeros); // [80, 10, 7, 5, 2] - decrescente

Para ordenar objetos, acesse a propriedade desejada dentro da função de comparação. Cuidado com a estabilidade da ordenação: versões antigas do JavaScript não garantiam estabilidade (elementos equivalentes mantêm a ordem relativa?), mas a partir do ES2019, o sort é estável.

Referências

Exercícios

  1. Use forEach para imprimir no console o quadrado de cada número do array [1, 2, 3, 4, 5].
  2. ✓ Resposta:
    [1, 2, 3, 4, 5].forEach(num => console.log(num * num));
  3. Dado o array [10, 20, 30, 40], use some para verificar se existe algum número maior que 35. Use every para verificar se todos são maiores que 5.
  4. ✓ Resposta:
    const nums = [10, 20, 30, 40];
    console.log(nums.some(n => n > 35)); // true
    console.log(nums.every(n => n > 5)); // true
  5. Dado o array de objetos const pessoas = [{nome: 'João', idade: 25}, {nome: 'Maria', idade: 30}, {nome: 'Pedro', idade: 20}], use find para encontrar a pessoa com nome 'Maria' e findIndex para encontrar o índice da pessoa com idade 20.
  6. ✓ Resposta:
    const pessoas = [
      { nome: 'João', idade: 25 },
      { nome: 'Maria', idade: 30 },
      { nome: 'Pedro', idade: 20 }
    ];
    
    const maria = pessoas.find(p => p.nome === 'Maria');
    console.log(maria); // { nome: 'Maria', idade: 30 }
    
    const indicePedro = pessoas.findIndex(p => p.idade === 20);
    console.log(indicePedro); // 2
  7. Ordene o array [3, 1, 4, 1, 5, 9, 2, 6] em ordem crescente e decrescente usando sort com função de comparação.
  8. ✓ Resposta:
    const arr = [3, 1, 4, 1, 5, 9, 2, 6];
    const crescente = [...arr].sort((a, b) => a - b);
    const decrescente = [...arr].sort((a, b) => b - a);
    console.log(crescente); // [1, 1, 2, 3, 4, 5, 6, 9]
    console.log(decrescente); // [9, 6, 5, 4, 3, 2, 1, 1]
  9. Dado o array de strings ['maçã', 'banana', 'abacaxi', 'laranja'], ordene-o em ordem alfabética decrescente. Dica: use localeCompare para comparação de strings.
  10. ✓ Resposta:
    const frutas = ['maçã', 'banana', 'abacaxi', 'laranja'];
    frutas.sort((a, b) => b.localeCompare(a));
    console.log(frutas); // ['maçã', 'laranja', 'banana', 'abacaxi']

Boas Práticas e Observações Finais

Sempre prefira métodos como map, filter, reduce e os vistos nesta aula ao invés de loops manuais, quando possível. Eles tornam o código mais declarativo e menos propenso a erros. Lembre-se de que sort modifica o array original; se quiser manter o original, faça uma cópia com [...array] ou array.slice() antes de ordenar. Além disso, para comparações de strings com acentos ou caracteres especiais, use localeCompare para resultados corretos.