Identificação
- Duração: 2 horas
- Tipo: teoria aplicada e laboratório
- Entrega: painel de métricas baseado em arrays
- Laboratório:
../exemplos/aula-2.4/index.html
Introdução
O que é um array?
Um array é uma estrutura do JavaScript usada para guardar uma sequência ordenada de valores:
const lessonNames = [
"Valores e tipos",
"Condições",
"Funções",
];
Arrays são úteis quando precisamos representar vários itens relacionados, como tarefas, usuários, mensagens ou aulas.
Array é um banco de dados?
Não. Um array existe na memória enquanto o JavaScript está executando. Ao recarregar a página, seus dados normalmente desaparecem.
Um banco de dados oferece persistência, consultas, controle de concorrência e outras garantias. Mais adiante, utilizaremos MySQL para armazenar informações. Nesta aula, o array será nossa coleção temporária para aprender a transformar dados.
Array e objeto são a mesma coisa?
Um array representa uma coleção ordenada:
const tasks = ["Estudar", "Praticar"];
Um objeto reúne propriedades de uma entidade:
const task = {
title: "Estudar",
status: "doing",
};
Na prática, usaremos frequentemente um array de objetos:
const tasks = [
{ title: "Estudar", status: "doing" },
{ title: "Praticar", status: "todo" },
];
Estudaremos objetos com mais profundidade na Aula 2.5.
Por que o primeiro índice é zero?
O primeiro valor está na posição 0:
const colors = ["azul", "verde", "laranja"];
colors[0]; // "azul"
colors[1]; // "verde"
colors[2]; // "laranja"
Por isso, o último índice válido é array.length - 1.
O que significa transformar dados?
Transformar dados é produzir uma nova representação a partir de uma coleção:
- selecionar somente tarefas abertas;
- converter tarefas em cartões;
- somar horas estimadas;
- ordenar por prioridade;
- descobrir se existe tarefa crítica.
JavaScript oferece métodos declarativos, como map, filter, reduce e sort.
Eles permitem expressar o que desejamos obter sem controlar manualmente cada
índice.
Onde isso aparece no projeto?
Nesta aula, uma coleção de tarefas alimentará um painel. Os controles aplicarão um fluxo de filtro, ordenação e cálculo de métricas sem alterar o array original.
Objetivos
Ao final da aula, o aluno deverá conseguir:
- criar e acessar arrays;
- explicar
lengthe índices; - adicionar e remover itens conscientemente;
- percorrer arrays com
for...ofeforEach; - transformar valores com
map; - selecionar valores com
filter; - encontrar itens com
find; - verificar coleções com
someeevery; - acumular resultados com
reduce; - ordenar dados sem alterar o array original;
- explicar mutação e imutabilidade;
- encadear transformações legíveis.
Pré-requisitos
- Aulas 2.1 a 2.3 concluídas;
- condições, repetições e funções;
- noções iniciais de objetos;
- navegador, DevTools e editor.
Pergunta orientadora
Como obter listas e métricas diferentes a partir dos mesmos dados sem destruir a coleção original?
Roteiro sugerido
| Etapa | Duração |
|---|---|
| Estrutura, índices e operações básicas | 25 min |
| Iteração e busca | 20 min |
map, filter e reduce |
35 min |
| Ordenação e imutabilidade | 15 min |
| Laboratório | 20 min |
| Revisão | 5 min |
1. Criando arrays
const emptyTasks = [];
const taskTitles = [
"Revisar HTML",
"Praticar JavaScript",
"Publicar projeto",
];
Arrays podem tecnicamente misturar tipos:
const mixedValues = ["texto", 42, true, null];
Entretanto, coleções com itens de formato consistente são mais previsíveis:
const estimates = [1, 2, 5, 3];
2. Acesso, tamanho e limites
const tasks = ["A", "B", "C"];
tasks.length; // 3
tasks[0]; // "A"
tasks[tasks.length - 1]; // "C"
tasks[10]; // undefined
length representa a posição seguinte ao último índice, não o último índice.
3. Verificando se é array
Array.isArray([]); // true
Array.isArray({}); // false
typeof não diferencia corretamente:
typeof []; // "object"
Para validar arrays, utilize Array.isArray.
4. Adicionar e remover
Final da coleção
const tasks = ["Estudar"];
tasks.push("Praticar");
const removed = tasks.pop();
pushadiciona ao final;popremove e retorna o último item;- ambos alteram o array original.
Início da coleção
tasks.unshift("Planejar");
const first = tasks.shift();
unshiftadiciona no início;shiftremove do início;- ambos alteram o array.
Alterações no início exigem reposicionar os índices existentes e podem ter custo maior em coleções grandes.
5. Mutação e imutabilidade
Mutação altera o valor existente:
const tasks = ["A", "B"];
tasks.push("C");
Criação imutável produz um novo array:
const tasks = ["A", "B"];
const updatedTasks = [...tasks, "C"];
Imutabilidade ajuda a:
- comparar versões;
- evitar alterações distantes e inesperadas;
- preservar o estado anterior;
- trabalhar com frameworks que detectam novas referências.
Não significa que todo uso de push seja proibido. Significa compreender se a
operação altera a entrada e escolher conscientemente.
6. Cópia rasa com spread
const original = ["A", "B"];
const copy = [...original];
Para objetos internos, a cópia é rasa:
const original = [{ title: "Estudar" }];
const copy = [...original];
copy[0].title = "Alterado";
console.log(original[0].title); // "Alterado"
Os dois arrays são diferentes, mas ainda apontam para o mesmo objeto interno.
7. for...of
for (const task of tasks) {
console.log(task.title);
}
Use quando deseja controle de fluxo como break, continue ou await.
8. forEach
tasks.forEach((task, index) => {
console.log(index, task.title);
});
forEach executa um callback para cada item e retorna undefined. Ele é adequado
para efeitos, como registrar informações. Não é a escolha para criar um novo array.
Não é possível encerrar um forEach com break.
9. map
map transforma cada item e retorna um novo array com o mesmo tamanho:
const tasks = [
{ title: "Estudar", estimate: 2 },
{ title: "Praticar", estimate: 3 },
];
const titles = tasks.map((task) => task.title);
// ["Estudar", "Praticar"]
Outro exemplo:
const doubledEstimates = tasks.map((task) => task.estimate * 2);
Pergunta para reconhecer map:
Quero converter cada item em outra representação?
10. Erro comum no map
Com chaves, use return:
const titles = tasks.map((task) => {
return task.title;
});
Sem retorno, o novo array conterá undefined:
const titles = tasks.map((task) => {
task.title;
});
Retorno implícito:
const titles = tasks.map((task) => task.title);
11. filter
filter mantém os itens cujo callback retorna verdadeiro:
const openTasks = tasks.filter((task) => task.status !== "done");
O resultado pode ter tamanho menor ou igual ao original.
const criticalTasks = tasks.filter(
(task) => task.priority === "critical",
);
Pergunta para reconhecer filter:
Quero manter apenas os itens que atendem a uma condição?
12. find e findIndex
find retorna o primeiro item encontrado:
const task = tasks.find((item) => item.id === 3);
Se nenhum item atender à condição, retorna undefined.
findIndex retorna o índice:
const index = tasks.findIndex((item) => item.id === 3);
Se não encontrar, retorna -1.
Use find para um item; use filter para uma coleção de itens.
13. some e every
some responde se pelo menos um item atende à regra:
const hasCriticalTask = tasks.some(
(task) => task.priority === "critical",
);
every responde se todos atendem:
const allTasksDone = tasks.every(
(task) => task.status === "done",
);
Ambos retornam booleanos e podem parar assim que a resposta estiver determinada.
Em um array vazio:
[].some(() => true); // false
[].every(() => false); // true
O resultado de every pode surpreender. Antes de exibir “todas concluídas”, confira
também se existem itens.
14. includes
const allowedStatuses = ["todo", "doing", "done"];
const isAllowed = allowedStatuses.includes("doing");
Para objetos, includes compara a referência:
const task = { id: 1 };
const tasks = [task];
tasks.includes(task); // true
tasks.includes({ id: 1 }); // false
Para procurar por propriedades, utilize find ou some.
15. reduce
reduce acumula os itens em um único resultado:
const totalHours = tasks.reduce((total, task) => {
return total + task.estimate;
}, 0);
Elementos:
total: acumulador;task: item atual;0: valor inicial.
Evolução:
0 + primeira estimativa
resultado + segunda estimativa
resultado + terceira estimativa
Sempre que possível, informe o valor inicial. Sem ele, arrays vazios podem causar erro e o tipo inicial pode ficar menos evidente.
16. Métricas com reduce
Podemos calcular várias métricas em uma passagem:
const metrics = tasks.reduce(
(summary, task) => {
summary.total += 1;
summary.totalHours += task.estimate;
if (task.status === "done") {
summary.completed += 1;
}
return summary;
},
{
total: 0,
completed: 0,
totalHours: 0,
},
);
Essa versão altera o objeto acumulador criado para aquela redução. Também poderíamos retornar um novo objeto a cada volta, com custo adicional. O importante é não alterar as tarefas de entrada.
17. sort altera o array
const numbers = [10, 2, 30];
numbers.sort();
// [10, 2, 30] em ordem de texto, não numérica
Para números:
numbers.sort((a, b) => a - b);
E lembre: sort modifica o array.
Ordenação sem alterar a entrada:
const sortedTasks = [...tasks].sort((a, b) => {
return a.estimate - b.estimate;
});
Ambientes modernos também possuem toSorted, que retorna um novo array:
const sortedTasks = tasks.toSorted(
(a, b) => a.estimate - b.estimate,
);
Neste curso, a cópia com spread será utilizada enquanto consideramos compatibilidade com navegadores.
18. Ordenação por prioridade
Podemos associar cada prioridade a um peso:
const priorityWeight = {
critical: 4,
high: 3,
planned: 2,
low: 1,
};
const sorted = [...tasks].sort((a, b) => {
return priorityWeight[b.priority] - priorityWeight[a.priority];
});
O comparador retorna:
- valor negativo:
avem antes; - zero: mantém equivalência de ordem;
- valor positivo:
bvem antes.
19. Encadeamento
Métodos que retornam arrays podem ser encadeados:
const visibleTitles = tasks
.filter((task) => task.status !== "done")
.sort((a, b) => a.estimate - b.estimate)
.map((task) => task.title);
Leia da esquerda para a direita:
- selecione tarefas abertas;
- ordene por estimativa;
- extraia os títulos.
Evite cadeias longas demais. Use variáveis intermediárias quando elas explicarem as etapas.
20. Fluxo do painel
O laboratório seguirá este fluxo:
tasks
→ filter por status
→ cópia + sort
→ map para elementos visuais
→ reduce para métricas
O array tasks permanece na ordem original. O painel também exibirá essa ordem para
que possamos comparar entrada e resultado.
21. Laboratório guiado
Abra o painel de métricas.
Etapa 1 — Filtre
Alterne entre todas, abertas e concluídas. Observe:
- o número de itens visíveis;
- a lista resultante;
- as etapas do fluxo.
Etapa 2 — Ordene
Ordene por prioridade, estimativa e título. Confirme que a ordem original indicada na página não muda.
Etapa 3 — Analise métricas
As métricas são calculadas com reduce sobre os itens visíveis:
- total;
- concluídas;
- horas estimadas;
- existência de prioridade crítica.
Etapa 4 — Inspecione o código
Localize:
filterTasks;sortTasks;calculateMetrics;renderTasks;some,filter,map,reduceesort.
22. Erros comuns
Confundir item com índice
tasks.map((index) => index.title);
O primeiro parâmetro é o item. Use nomes coerentes:
tasks.map((task) => task.title);
Não retornar no callback
tasks.filter((task) => {
task.status === "done";
});
Use:
tasks.filter((task) => {
return task.status === "done";
});
Alterar o original com sort
const sorted = tasks.sort(compareTasks);
Use uma cópia:
const sorted = [...tasks].sort(compareTasks);
Usar map apenas para efeitos
Se não utilizar o array retornado e deseja somente executar um efeito, forEach ou
for...of comunica melhor a intenção.
Usar reduce para tudo
reduce é poderoso, mas um filter ou map simples costuma ser mais legível.
Escolha o método que expressa a operação.
23. Boas práticas
- mantenha itens com estrutura consistente;
- use
Array.isArraypara validar; - escolha métodos pela intenção;
- não altere entradas de funções de transformação;
- copie antes de ordenar;
- forneça valor inicial ao
reduce; - nomeie acumulador e item claramente;
- divida fluxos complexos em etapas;
- trate arrays vazios;
- preserve regras puras separadas do DOM.
24. Exercícios
Exercício 1 — Títulos
Use map para criar um array somente com os títulos.
Exercício 2 — Pendências
Use filter para selecionar tarefas não concluídas.
Exercício 3 — Busca
Use find para localizar uma tarefa por id.
Exercício 4 — Verificações
Use some para descobrir se existe tarefa crítica e every para verificar se todas
estão concluídas.
Exercício 5 — Soma
Use reduce para calcular o total de horas.
Exercício 6 — Ordem imutável
Ordene por título sem modificar a coleção original.
25. Desafio
Amplie o laboratório:
- adicione filtro por prioridade;
- combine filtro de status e prioridade;
- exiba média de horas;
- crie agrupamento por status com
reduce; - mantenha a ordem original intacta;
- mostre um estado vazio quando nenhum item atender aos filtros.
26. Lista de verificação de conclusão
- Sei explicar array e índice.
- Sei diferenciar array e banco de dados.
- Consigo escolher entre
map,filterereduce. - Sei quando usar
find,someeevery. - Entendo que
sortaltera o array. - Consigo ordenar uma cópia.
- Sei explicar cópia rasa.
- Consigo ler um fluxo encadeado.
- Testei filtros com resultado vazio.
- Confirmei que a entrada original foi preservada.
27. Critérios de avaliação
| Critério | Pontos |
|---|---|
| Uso correto de métodos de array | 30 |
Métricas com reduce |
20 |
| Ordenação sem mutar a entrada | 20 |
| Filtros e estados vazios | 15 |
| Funções puras e legibilidade | 10 |
| Acessibilidade | 5 |
| Total | 100 |
Resumo
Nesta aula, aprendemos que:
- arrays representam sequências ordenadas;
- índices começam em zero;
maptransforma,filterseleciona ereduceacumula;find,someeeveryrespondem perguntas sobre a coleção;sortaltera o array e deve ser aplicado a uma cópia quando desejamos preservar a entrada;- fluxos convertem os mesmos dados em diferentes visualizações e métricas.
Próxima aula
Na Aula 2.5, aprofundaremos objetos, desestruturação, cópias, modelagem de entidades e conversão entre objetos JavaScript e JSON.