ID = -> x { x } # Why is the identity function not in the core lib?
f = <<-HERE
0101
1010
1311
0101
1311
431
1010
431
420
HERE
Hash[f.lines.map(&:to_i).group_by(&ID).map {|n, ns| [n, ns.size] }]
# { 101 => 2, 1010 => 2, 1311 => 2, 431 => 2, 420 => 1 }
Simplemente grupo de los números por sí mismos utilizando Enumerable#group_by
, que le da algo así como
{ 101 => [101, 101], 420 => [420] }
y luego se Enumerable#map
el valor las matrices a sus longitudes, es decir [101, 101]
se convierte en 2
. A continuación, simplemente conviértalo de nuevo a Hash
usando Hash::[]
.
Sin embargo, si está dispuesto a utilizar una biblioteca de terceros, se vuelve aún más trivial, porque si utiliza una estructura de datos MultiSet
, la respuesta se cae naturalmente. (A MultiSet
es como un Set
, con la excepción de que un artículo se puede añadir varias veces y la MultiSet
será llevar la cuenta de cuántas veces se añadió un artículo – que es exactamente lo que quiere.)
require 'multiset' # Google for it, it's so old that it isn't available as a Gem
Multiset[*f.lines.map(&:to_i)]
# => #<Multiset:#2 101, #2 1010, #2 1311, #2 431, #1 420>
Sí, eso es eso.
Eso es lo mejor de usar la estructura de datos correcta: sus algoritmos se vuelven enormemente más simples. O, en este caso particular, el algoritmo solo desaparece.
He escrito más sobre el uso MultiSet
s para la solución de este problema exacto en
Creo que he encontrado la misma pregunta con una redacción diferente :) [count elementos duplicados en la matriz de rubí] (http://stackoverflow.com/questions/569694/count-duplicate-elements-in-ruby-array) – Matchu
:) eso es genial. Gracias. – josh
FYI: Si se trata de Rails, puede usar Enumerable # group_by. Consulte http://api.rubyonrails.org/classes/Enumerable.html#method-i-group_by –