Ruby é uma linguagem de programação que possui uma grande variedade de métodos que nos ajudam a executar ações comuns, como agrupar elementos de arrays, por exemplo. Uma maneira de agrupar elementos iguais em uma coleção é usando o método group_by
indicando a regra de seleção com &:itself
:
letras = ['a', 'a', 'b', 'a', 'c', 'd', 'd']
letras.group_by(&:itself)
# => {"a"=>["a", "a", "a"], "b"=>["b"], "c"=>["c"], "d"=>["d", "d"]}
O método retorna uma Hash, mostrando o elemento com todas as ocorrências em que a regra foi verdadeira. Para contar quantas vezes os elementos se repetem dentro dessa coleção, independente da ordem em que aparecem, poderíamos fazer algo como:
letras.group_by(&:itself).map { |k,v| "#{k}: #{v.count}" }
# => ["a: 3", "b: 1", "c: 1", "d: 2"]
Mas o Ruby tem um método que torna isso ainda mais fácil, o método tally
, introduzido na versão 2.7. Com ele isso ficaria assim:
letras.tally
# => {"a"=>3, "b"=>1, "c"=>1, "d"=>2}
Aqui ainda temos uma Hash como retorno, mas cada elemento vem associado somente ao número de vezes que ele foi repetido na coleção.