Fácil JavaScript

Contando ocorrências com Map

Enunciado

Escreva uma função contarOcorrencias(array) que recebe um array de strings e retorna um Map onde cada chave é um elemento e o valor é a quantidade de vezes que ele aparece.

Requisitos

  • A função deve retornar um Map.
  • Cada chave deve ser um elemento do array original.
  • O valor associado deve ser o número de ocorrências.
  • O array de entrada não deve ser modificado.

Código inicial

function contarOcorrencias(array) {
  // seu código aqui
}

console.log(contarOcorrencias(['a', 'b', 'a', 'c', 'b', 'a']));

Saída esperada

Map(3) { 'a' => 3, 'b' => 2, 'c' => 1 }
Ver dica

Use map.get(chave) para obter o valor atual e map.set(chave, valor) para atualizar. Se a chave não existir, get retorna undefined.

Mostrar solução
function contarOcorrencias(array) {
  const contagem = new Map();
  for (const item of array) {
    // Se já existe, incrementa; senão, começa com 1
    contagem.set(item, (contagem.get(item) || 0) + 1);
  }
  return contagem;
}

console.log(contarOcorrencias(['a', 'b', 'a', 'c', 'b', 'a']));

Passo a passo

  1. Criamos um novo Map vazio chamado contagem.
  2. Iteramos sobre cada elemento do array com for...of.
  3. Para cada item, usamos contagem.get(item) para obter a contagem atual. Se for undefined, usamos || 0 para tratar como zero.
  4. Somamos 1 e usamos contagem.set(item, novoValor) para atualizar o mapa.
  5. Após o loop, retornamos o Map com todas as contagens.

Por que funciona

O Map é ideal aqui porque as chaves podem ser strings (ou qualquer outro tipo) e mantém a ordem de inserção. Diferente de um objeto, não há conversão de chaves para string, então se o array tivesse números ou objetos, o comportamento seria consistente. Além disso, get e set são operações diretas e eficientes.

Erros comuns

  • Esquecer o || 0: contagem.get(item) + 1 resulta em NaN na primeira ocorrência, pois undefined + 1 é NaN. Corrija com (contagem.get(item) || 0) + 1.
  • Usar objeto em vez de Map: const obj = {}; obj[item] = ... funciona para strings, mas se item for um objeto, a chave vira '[object Object]', causando contagens erradas.
  • Modificar o array original: não é o caso aqui, mas evite usar array.shift() ou splice dentro do loop.

Outra forma de resolver

Usando reduce:

function contarOcorrencias(array) {
  return array.reduce((map, item) => {
    map.set(item, (map.get(item) || 0) + 1);
    return map;
  }, new Map());
}

Essa abordagem é mais funcional, mas menos legível para iniciantes.

Saída esperada

Map(3) { 'a' => 3, 'b' => 2, 'c' => 1 }