Iteração avançada em arrays
Esta aula aborda métodos avançados de iteração em arrays em JavaScript, incluindo forEach, some/every, find/findIndex e sort, com exemplos práticos e explicações detalhadas para evitar pegadinhas comuns.
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
- MDN: Array.prototype.forEach
- MDN: Array.prototype.some
- MDN: Array.prototype.every
- MDN: Array.prototype.find
- MDN: Array.prototype.findIndex
- MDN: Array.prototype.sort
- JavaScript.info: Array methods
Exercícios
- Use
forEachpara imprimir no console o quadrado de cada número do array[1, 2, 3, 4, 5]. - Dado o array
[10, 20, 30, 40], usesomepara verificar se existe algum número maior que 35. Useeverypara verificar se todos são maiores que 5. - Dado o array de objetos
const pessoas = [{nome: 'João', idade: 25}, {nome: 'Maria', idade: 30}, {nome: 'Pedro', idade: 20}], usefindpara encontrar a pessoa com nome 'Maria' efindIndexpara encontrar o índice da pessoa com idade 20. - Ordene o array
[3, 1, 4, 1, 5, 9, 2, 6]em ordem crescente e decrescente usandosortcom função de comparação. - Dado o array de strings
['maçã', 'banana', 'abacaxi', 'laranja'], ordene-o em ordem alfabética decrescente. Dica: uselocaleComparepara comparação de strings.
[1, 2, 3, 4, 5].forEach(num => console.log(num * num));
const nums = [10, 20, 30, 40];
console.log(nums.some(n => n > 35)); // true
console.log(nums.every(n => n > 5)); // true
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
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]
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.