Contar as ocorrências de elemento em array

Neste artigo você vai aprender a como contar as ocorrências de elemento em array, ou seja, a frequência que os elementos aparecem em um array com JS

Contar as ocorrências de elemento em array capa

Fala programador(a), beleza? Bora aprender mais sobre arrays em JavaScript!

A estratégia que vamos utilizar aqui é transformar o array em um objeto, com os seus valores como nome das propriedades

E os valores das propriedades será a frequência que o elemento se repetiu no array

Podemos fazer essa transformação de array em objeto com o método reduce

Veja um exemplo de código:

const arr = [1, 2, 2, 3, 3, 4, 4, 4, 4]

const occurrences = arr.reduce((acc, curr) => {
  return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
}, {});

console.log(occurrences) // {1: 1, 2: 2, 3: 2, 4: 4}

Dentro do reduce temos um if ternário, que faz a verificação da iteração atual, se ela já existe no objeto final

Se existir, incrementamos o número de ocorrências

Se não existir, temos a definição do seu valor como 1, já que é a primeira vez que este item aparece

Desta maneira temos um objeto se formando, onde apresentou os itens e a quantidade de vezes que eles apareceram no array original

Deixe um comentário contando o que achou deste artigo 🙂

Formação Claude Code
Formação Recomendada

Formação Claude Code

Domine Claude Code do absoluto zero até o avançado

  • 114 aulas
  • 4 projetos
  • 9h 15min

Quer aprender mais sobre JavaScript? Confira o vídeo abaixo:

Conclusão

Neste artigo você aprendeu a como contar as ocorrências de elemento em array utilizando JavaScript

Ou seja, vimos como obter a frequência em que os elementos aparecem em uma lista

Geramos um objeto a partir do array, utilizando o método reduce

Neste objeto final temos os itens e quantas vezes eles apareceram no array

Está buscando a sua primeira vaga como Programador? Confira o nosso treinamento completo clicando aqui.

Uma plataforma de cursos com projetos completos, comunidade de alunos e muito mais!

Há também o nosso canal no YouTube, com muito conteúdo gratuito de qualidade!

Contando as ocorrências de um elemento específico:

Nem sempre tu quer a frequência de TODOS os itens, né?

Às vezes a pergunta é bem mais direta: quantas vezes o número 4 aparece nesse array?

Pra esse caso o reduce é um canhão pra matar mosquito, dá pra resolver com filter e length


const total = arr.filter((item) => item === 4).length

console.log(total) // 4

O filter devolve um novo array só com os itens que passaram no teste

E o length desse novo array é justamente a quantidade de ocorrências que a gente queria

Repare que o array original não é alterado em nenhum momento, o filter sempre gera uma lista nova 🙂

Uma versão mais legível com forEach:

Se liga, aquele reduce com vírgula no meio funciona, mas ele assusta bastante quem tá começando

E código que tu não entende em 3 segundos é código que tu não vai manter depois

Então vale conhecer a versão "feijão com arroz", que faz exatamente a mesma coisa:


const occurrences = {}

arr.forEach((item) => {
})

console.log(occurrences) // {js: 3, python: 1, php: 1}

O truque tá no || 0

Quando a chave ainda não existe no objeto, o valor lido é undefined, e o || entrega o 0 no lugar

Aí soma 1 e pronto, o item entra no objeto com a primeira ocorrência contada

Mesmo resultado do reduce, só que sem ternário e sem vírgula escondida no meio da linha

E se o array for de objetos?

Aqui a coisa muda de figura, porque objeto não vira nome de propriedade que preste

O que a gente conta na real é uma PROPRIEDADE dos objetos, tipo a linguagem de cada dev da lista:

const devs = [
{ nome: 'Matheus', lang: 'js' },
{ nome: 'Ana', lang: 'python' },
{ nome: 'João', lang: 'js' }
]

const porLang = devs.reduce((acc, dev) => {
return acc
}, {})

console.log(porLang) // {js: 2, python: 1}

A lógica é idêntica à do array de números, só trocamos o item pela propriedade que interessa

Tome cuidado com um detalhe: se a propriedade não existir em algum objeto da lista, tu vai ver uma chave undefined aparecer no resultado

É o tipo de bug que passa despercebido em array grande, então confere sempre a saída no console

Qual é o elemento que mais se repete?

Depois que tu tem o objeto de ocorrências em mãos, essa é a pergunta natural que vem em seguida

E ela é bem barata de responder, é só varrer as chaves comparando os valores:


const occurrences = {}

arr.forEach((item) => {
})

const maisRepetido = Object.keys(occurrences).reduce((a, b) => {
})

console.log(maisRepetido) // '4'

Repara na aspa ali no resultado

O Object.keys sempre devolve as chaves como texto, então mesmo que o array fosse de números tu recebe uma string de volta

Se precisar do número mesmo, é só jogar um Number() em cima e seguir o baile 😀

Contando com Map em vez de objeto:

Tem uma armadilha silenciosa na estratégia do objeto, e ela morde quando o array tem tipos misturados

Nome de propriedade em objeto é sempre texto, então o número 1 e a string ‘1’ viram a MESMA chave e a contagem sai errada

Quando isso importa, a saída é usar Map:


const occurrences = new Map()

for (const item of arr) {
occurrences.set(item, (occurrences.get(item) || 0) + 1)
}

console.log(occurrences)

O Map guarda a chave com o tipo original, então 1 e ‘1’ ficam separados como deveriam

A leitura de um valor é feita com get e a escrita com set, é só isso de diferente

Pra array de um tipo só, o objeto resolve numa boa, use Map quando o dado vier bagunçado (leia-se: quando vier de uma API 😛)

Perguntas frequentes:

Como contar quantas vezes um elemento aparece em um array?

Usando filter pra separar só as ocorrências daquele item e length pra saber o tamanho do resultado: arr.filter((item) => item === valor).length

Dá pra contar as ocorrências sem usar reduce?

Dá sim, com forEach ou com um for…of, criando um objeto vazio e somando 1 em cada chave conforme os itens passam

O reduce é mais enxuto, o forEach é mais fácil de ler, os dois entregam o mesmo objeto no final

Por que as chaves do objeto aparecem em ordem crescente?

Porque chaves que parecem número inteiro são organizadas primeiro e em ordem crescente pelo JavaScript, não é o reduce fazendo isso

Se a ordem de entrada importar pra ti, use Map, que preserva a ordem em que os itens foram inseridos

O array original é alterado nesse processo?

Não, nem o reduce nem o filter mexem no array de origem, ambos entregam um valor novo

E se eu quiser contar ignorando maiúsculas e minúsculas?

Normalize o item antes de usar como chave, tipo item.toLowerCase() dentro do forEach, aí ‘JS’ e ‘js’ caem na mesma contagem

Leia também

Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares