JavaScript: Arrays Avançados em JavaScript

Na lição anterior, você aprendeu operações básicas com arrays. Agora vamos subir de nível com "movimentos de poder" dos arrays — métodos de ordem superior. Estes permitem fazer mais com menos código e são habilidades essenciais no desenvolvimento JavaScript moderno.

1. map — Transformar Cada Elemento

map executa uma função em cada elemento e retorna um novo array — o original permanece inalterado. Pense nele como uma linha de montagem: cada elemento entra, é transformado e sai como parte de um novo produto.

HTML
<script>
let prices = [10, 20, 30];
let doubled = prices.map(p => p * 2);   // [20, 40, 60]
</script>

O callback recebe três argumentos: (elemento, índice, arrayOriginal). Na maioria das vezes você só precisa do primeiro.


▶ Exemplo

JAVASCRIPT
// Exemplo de código desta seção
const message = "Olá, Mundo!";
console.log(message);
▶ Experimente

Este é o exemplo mais simples; as seções seguintes explicarão em detalhes.## 2. filter — Manter o Que Passa

filter mantém elementos que passam em um teste e retorna um novo array — o original não é tocado. Como um ponto de segurança: itens que atendem aos critérios passam; o resto é filtrado.

HTML
<script>
let scores = [45, 80, 92, 55, 78, 98];
let passed = scores.filter(s => s >= 60);  // [80, 92, 78, 98]
</script>

Elementos onde o callback retorna true são mantidos; aqueles que retornam false são descartados.


3. reduce — Acumular em Um Valor Só

reduce "comprime" um array em um único valor. O caso de uso mais comum é somar:

HTML
<script>
let nums = [1, 2, 3, 4, 5];
let sum = nums.reduce((acc, cur) => acc + cur, 0);  // 15
</script>

O que os parâmetros significam:

💡 Dica: reduce parece complicado no início, mas sua essência é simples: passo a passo, comprima o array em um valor só. Soma, encontrar o máximo, contar ocorrências — resolve cuida de todos.

▶ Exemplo: Combinando map, filter e reduce

HTML
<!DOCTYPE html>
<html lang="pt-br">
<body>
  <h2>map / filter / reduce</h2>
  <div id="output"></div>
  <script>
    let products = [
      { name: 'Notebook', price: 4999, category: 'Eletrônicos' },
      { name: 'Camiseta', price: 79, category: 'Roupas' },
      { name: 'Mouse', price: 149, category: 'Eletrônicos' },
      { name: 'Calça Jeans', price: 199, category: 'Roupas' },
      { name: 'Teclado', price: 299, category: 'Eletrônicos' }
    ];

    let html = '<strong>Todos os Produtos:</strong><br>';
    products.forEach(p => html += `${p.name} - R$${p.price} (${p.category})<br>`);

    let electronics = products.filter(p => p.category === 'Eletrônicos');
    html += '<br><strong>Eletrônicos (filter):</strong><br>';
    electronics.forEach(p => html += `${p.name} - R$${p.price}<br>`);

    let names = products.map(p => p.name);
    html += '<br><strong>Nomes dos Produtos (map):</strong>' + names.join(', ') + '<br>';

    let total = products.reduce((sum, p) => sum + p.price, 0);
    html += '<br><strong>Preço Total (reduce):</strong>R$' + total;

    document.getElementById('output').innerHTML = html;
  </script>
</body>
</html>
▶ Experimente

4. find e findIndex

Se nada for encontrado, find retorna undefined e findIndex retorna -1.

HTML
<script>
let users = [
  { name: 'Alice', age: 20 },
  { name: 'Bob', age: 17 },
  { name: 'Charlie', age: 25 }
];

users.find(u => u.age > 22);       // { name: 'Charlie', age: 25 }
users.findIndex(u => u.age < 18);  // 1 (índice do Bob)
</script>

5. sort — Ordenar Elementos

sort organiza o array no local (modifica o original!). Por padrão, ordena como strings, o que engana muitos iniciantes:

HTML
<script>
let nums = [10, 1, 21, 2];
nums.sort();           // [1, 10, 2, 21]  ← Ordenação de string! "10" < "2"

// Correto: ordenação numérica requer uma função comparadora
nums.sort((a, b) => a - b);   // [1, 2, 10, 21]  ← Crescente
nums.sort((a, b) => b - a);   // [21, 10, 2, 1]  ← Decrescente
</script>
⚠️ Nota: sort muta o array original! Para manter o original intacto, copie primeiro: [...arr].sort(...).

▶ Exemplo: Ordenando Notas de Alunos

HTML
<!DOCTYPE html>
<html lang="pt-br">
<body>
  <h2>Ranking de Notas dos Alunos</h2>
  <div id="output"></div>
  <script>
    let students = [
      { name: 'Alice', score: 72 },
      { name: 'Bob', score: 95 },
      { name: 'Charlie', score: 88 },
      { name: 'Diana', score: 61 },
      { name: 'Eve', score: 95 }
    ];

    let html = '<strong>Ordem Original:</strong><br>';
    students.forEach(s => html += `${s.name} - ${s.score}<br>`);

    let byScore = [...students].sort((a, b) => b.score - a.score);
    html += '<br><strong>Ordenado por Nota (Decrescente):</strong><br>';
    byScore.forEach((s, i) => {
      let medal = i === 0 ? '🥇' : i === 1 ? '🥈' : i === 2 ? '🥉' : '';
      html += `${medal} ${s.name} - ${s.score}<br>`;
    });

    let topStudents = students.filter(s => s.score >= 90);
    html += '<br><strong>90 ou Acima (filter):</strong><br>';
    topStudents.forEach(s => html += `${s.name} - ${s.score}<br>`);

    let found = students.find(s => s.name === 'Charlie');
    html += `<br><strong>Encontrar "Charlie" (find):</strong>${found ? found.score : 'Não encontrado'}`;

    document.getElementById('output').innerHTML = html;
  </script>
</body>
</html>
▶ Experimente

6. some e every

HTML
<script>
let scores = [60, 75, 82, 90];

scores.some(s => s >= 90);    // true  — alguém tirou 90+
scores.some(s => s === 100);  // false — ninguém tirou nota perfeita
scores.every(s => s >= 60);   // true  — todos passaram
</script>
💡 Dica: some pergunta "existe alguém que...", enquanto every pergunta "todos...". Um verifica existência; o outro verifica completude.


7. Operador Spread (...)

O operador spread ... "desempacota" um array. É comumente usado para copiar e mesclar:

HTML
<script>
let a = [1, 2, 3];
let b = [...a];          // Cópia: [1, 2, 3] (novo array, não uma referência)
let c = [...a, 4, 5];    // Mesclagem: [1, 2, 3, 4, 5]
let d = [0, ...a, 4];    // Inserção: [0, 1, 2, 3, 4]

let x = [1, 2], y = [3, 4];
let z = [...x, ...y];    // [1, 2, 3, 4]
</script>

8. Desestruturação

Extraia valores de um array e atribua-os a variáveis por posição:

HTML
<script>
let [a, b, c] = [1, 2, 3];
// a = 1, b = 2, c = 3

let [first, ...rest] = [1, 2, 3, 4, 5];
// first = 1, rest = [2, 3, 4, 5]

let [nome, nota] = ['Alice', 95];
// nome = 'Alice', nota = 95
</script>
💡 Dica: A desestruturação mantém o código conciso. Quando uma função retorna múltiplos valores, encapsulá-los em um array e desestruturar é um padrão comum.


9. Encadeamento de Métodos

Métodos de ordem superior retornam novos arrays, então você pode encadeá-los um após o outro:

HTML
<script>
let result = students
  .filter(s => s.score >= 60)     // Primeiro, filtra alunos aprovados
  .map(s => s.name)               // Depois, extrai nomes
  .sort();                         // Por fim, ordena
</script>

▶ Exemplo: Encadeamento para Processar Dados

HTML
<!DOCTYPE html>
<html lang="pt-br">
<body>
  <h2>Encadeamento de Métodos</h2>
  <div id="output"></div>
  <script>
    let employees = [
      { name: 'Alice', dept: 'Engenharia', salary: 8000 },
      { name: 'Bob', dept: 'Vendas', salary: 5000 },
      { name: 'Charlie', dept: 'Engenharia', salary: 12000 },
      { name: 'Diana', dept: 'Vendas', salary: 6500 },
      { name: 'Eve', dept: 'Engenharia', salary: 10000 },
      { name: 'Frank', dept: 'Marketing', salary: 5500 }
    ];

    let html = '<strong>Todos os Funcionários:</strong><br>';
    employees.forEach(e => html += `${e.name} | ${e.dept} | R$${e.salary}<br>`);

    let techHighSalary = employees
      .filter(e => e.dept === 'Engenharia')
      .filter(e => e.salary >= 9000)
      .map(e => `${e.name}(R$${e.salary})`);
    html += '<br><strong>Engenheiros de Alto Salário (filter+map encadeado):</strong><br>' + techHighSalary.join(', ');

    let avgSalary = employees
      .filter(e => e.dept === 'Engenharia')
      .map(e => e.salary)
      .reduce((sum, s) => sum + s, 0);
    let count = employees.filter(e => e.dept === 'Engenharia').length;
    html += `<br><br><strong>Salário Médio de Engenharia:</strong>R$${(avgSalary / count).toFixed(0)}`;

    let allAbove3k = employees.every(e => e.salary > 3000);
    let has12k = employees.some(e => e.salary >= 12000);
    html += `<br><br><strong>Todos os salários > R$3000?</strong>${allAbove3k ? 'Sim' : 'Não'}`;
    html += `<br><strong>Alguém ganha ≥ R$12000?</strong>${has12k ? 'Sim' : 'Não'}`;

    document.getElementById('output').innerHTML = html;
  </script>
</body>
</html>
▶ Experimente

▶ Exemplo: Operador Spread e Desestruturação

HTML
<!DOCTYPE html>
<html lang="pt-br">
<body>
  <h2>Operador Spread e Desestruturação</h2>
  <div id="output"></div>
  <script>
    let a = [1, 2, 3];
    let b = [...a];
    b.push(4);
    let html = `<strong>Copiando com Spread:</strong><br>`;
    html += `Array original a: [${a}]<br>`;
    html += `Cópia b: [${b}]<br>`;
    html += `Modificar b não afeta a<br><br>`;

    let x = [1, 2], y = [3, 4];
    let merged = [...x, ...y, 5];
    html += `<strong>Array Mesclado:</strong>[${merged}]<br><br>`;

    let [first, second, ...rest] = [10, 20, 30, 40, 50];
    html += `<strong>Desestruturação:</strong><br>`;
    html += `first = ${first}<br>`;
    html += `second = ${second}<br>`;
    html += `rest = [${rest}]<br><br>`;

    let scores = [85, 92, 78, 95, 60];
    let [highest, ...others] = [...scores].sort((a, b) => b - a);
    html += `<strong>Desestruturação + Sort:</strong><br>`;
    html += `Maior = ${highest}<br>`;
    html += `Outros = [${others}]`;

    document.getElementById('output').innerHTML = html;
  </script>
</body>
</html>
▶ Experimente

❓ Perguntas Frequentes

P:Qual a diferença entre map e forEach? R:map retorna um novo array; forEach retorna undefined. Use map quando precisar do resultado, forEach quando só quer executar uma ação. Não faça push manual dentro de forEach — para isso serve o map.

P:Por que sort modifica o array original? R:É uma escolha de design histórica. sort é uma operação no local — reorganiza os elementos em vez de retornar um novo array. Para preservar o original, copie primeiro: [...arr].sort(...).

P:Posso omitir o valor inicial no reduce? R:Sim — se omitido, o primeiro elemento se torna o valor inicial e a iteração começa do segundo. Mas um array vazio sem valor inicial lançará um erro, então sempre forneça um por segurança.

📖 Resumo


📝 Exercícios

  1. Dado o array [3, 8, 12, 5, 9, 17, 4], use filter para manter números maiores que 7, depois map para dobrá-los. Exiba o resultado.
  2. Use reduce para contar a ocorrência de cada palavra em um array como ['maçã', 'banana', 'maçã', 'cereja', 'banana', 'maçã']{ maçã: 3, banana: 2, cereja: 1 }.
  3. Dado um array de alunos (com nome e nota), use encadeamento para: filtrar alunos aprovados → ordenar por nota decrescente → extrair nomes em um novo array. Exiba o resultado na página.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%