example array ruby sorting hashmap

array - Ordena hash por clave, vuelve hash en Ruby



hash.map ruby (10)

Ordena hash por clave , vuelve hash en Ruby

Con desestructuración y Hash # sort.

hash.sort { |(ak, _), (bk, _)| ak <=> bk }.to_h

Enumerable # sort_by

hash.sort_by { |k, v| k }.to_h

Hash # ordenar con comportamiento predeterminado

h = { "b" => 2, "c" => 1, "a" => 3 } h.sort # e.g. ["a", 20] <=> ["b", 30] hash.sort.to_h #=> { "a" => 3, "b" => 2, "c" => 1 }

Nota: <Ruby 2.1

array = [["key", "value"]] hash = Hash[array] hash #=> {"key"=>"value"}

Nota:> Ruby 2.1

[["key", "value"]].to_h #=> {"key"=>"value"}

¿Sería esta la mejor manera de ordenar un hash y devolver un objeto Hash (en lugar de Array):

h = {"a"=>1, "c"=>3, "b"=>2, "d"=>4} # => {"a"=>1, "c"=>3, "b"=>2, "d"=>4} Hash[h.sort] # => {"a"=>1, "b"=>2, "c"=>3, "d"=>4}


En Ruby 2.1 es simple:

h.sort.to_h


Me gustó la solución en el post anterior.

Hice una mini-clase, la llamé class AlphabeticalHash . También tiene un método llamado ap , que acepta un argumento, un Hash , como entrada: ap variable . Similar a pp ( pp variable )

Pero (intentará) imprimirá en la lista alfabética (sus claves). No sé si alguien más quiere usar esto, está disponible como una gema, puede instalarlo como tal: gem install alphabetical_hash

Para mí, esto es lo suficientemente simple. Si otros necesitan más funcionalidad, hágamelo saber, lo incluiré en la gema.

EDITAR: Crédito es para , quien me dio la idea. :)


No, no lo es (Ruby 1.9.x)

require ''benchmark'' h = {"a"=>1, "c"=>3, "b"=>2, "d"=>4} many = 100_000 Benchmark.bm do |b| GC.start b.report("hash sort") do many.times do Hash[h.sort] end end GC.start b.report("keys sort") do many.times do nh = {} h.keys.sort.each do |k| nh[k] = h[k] end end end end user system total real hash sort 0.400000 0.000000 0.400000 ( 0.405588) keys sort 0.250000 0.010000 0.260000 ( 0.260303)

Para grandes hashes la diferencia crecerá hasta 10x y más.


Nota: Ruby> = 1.9.2 tiene un hash de conservación de orden: las claves de orden que se insertan serán el orden en que se enumeran. Lo siguiente se aplica a versiones anteriores o a código compatible con versiones anteriores.

No hay concepto de un hash ordenado. Así que no, lo que estás haciendo no está bien.

Si desea que esté ordenado para su visualización, devuelva una cadena:

"{" + h.sort.map{|k,v| "#{k.inspect}=>#{v.inspect}"}.join(", ") + "}"

O, si quieres las llaves en orden:

h.keys.sort

O, si quieres acceder a los elementos en orden:

h.sort.map do |key,value| # keys will arrive in order to this block, with their associated value. end

pero en resumen, no tiene sentido hablar de un hash ordenado. De los docs , "El orden en el que atraviesa un hash por clave o valor puede parecer arbitrario, y generalmente no estará en el orden de inserción". Así que insertar claves en un orden específico en el hash no ayudará.


Siempre he usado sort_by . #sort_by envolver la salida #sort_by con Hash[] para hacer que #sort_by un hash, de lo contrario, genera una matriz de matrices. Alternativamente, para lograr esto, puede ejecutar el método #to_h en la matriz de tuplas para convertirlas en una estructura k=>v (hash).

hsh ={"a" => 1000, "b" => 10, "c" => 200000} Hash[hsh.sort_by{|k,v| v}] #or hsh.sort_by{|k,v| v}.to_h

Hay una pregunta similar en " ¿Cómo ordenar un Ruby Hash por valor numérico? ".


Te diste la mejor respuesta en el OP: Hash[h.sort] Si deseas más posibilidades, aquí está la modificación en el lugar del hash original para que sea ordenado:

h.keys.sort.each { |k| h[k] = h.delete k }


Tuve el mismo problema (tuve que ordenar mis equipos por su nombre) y lo resolví así:

<% @equipments.sort.each do |name, quantity| %> ... <% end %>

@equipments es un hash que compilo en mi modelo y devuelvo en mi controlador. Si llama a .sort, ordenará el hash en función de su valor clave.



@ordered = {} @unordered.keys.sort.each do |key| @ordered[key] = @unordered[key] end