404 Not Found

404 Not Found


nginx

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.

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.

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.

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:

💡 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

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>

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>
⚠️ 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

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>
💡 some pergunta "existe alguém que...", enquanto every pergunta "todos...". Um verifica existência; o outro verifica completude.

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>

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>
💡 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.

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

📖 Resumo

  1. map transforma cada elemento em um novo array, filter mantém elementos correspondentes, reduce acumula em um único valor
  2. find retorna o primeiro elemento correspondente, findIndex retorna o primeiro índice correspondente
  3. sort por padrão ordena como string — para números, sempre passe um comparador: (a, b) => a - b
  4. some verifica se algum elemento corresponde, every verifica se todos os elementos correspondem
  5. O operador spread ... copia e mescla arrays; desestruturação extrai elementos em variáveis
  6. Métodos de ordem superior retornam novos arrays e podem ser encadeados para código conciso e legível

❓ 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.

📝 Atividades

  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.
100%