¿Cómo ordenar un Hash Ruby por valor numérico?


Tengo un contador hash que estoy tratando de ordenar por conteo. El problema con el que me estoy topando es que el Hash predeterminado.la función sort ordena números como cadenas en lugar de por tamaño de número.

Es decir, dado Hash:

metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" => 10 }

Ejecutando este código:

metrics.sort {|a1,a2| a2[1]<=>a1[1]}

Devolverá una matriz ordenada:

[ 'siteb.com', 9, 'sitea.com', 745, 'sitec.com', 10]

Aunque 745 es un número mayor que 9, 9 aparecerá primero en la lista. Al tratar de mostrar quién tiene la cuenta superior, esto está haciendo mi vida difícil. :)

Cualquier idea sobre ¿cómo ordenar un hash (o un array even) por tamaño de valor numérico?

Agradezco cualquier ayuda.

 136
Author: Marc-André Lafortune, 2010-03-29

4 answers

No tengo idea de cómo obtuvo sus resultados, ya que no ordenaría por valor de cadena... Deberías invertir a1 y a2 en tu ejemplo

La mejor manera en cualquier caso (según Mladen) es:

metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" => 10 }
metrics.sort_by {|_key, value| value}
  # ==> [["siteb.com", 9], ["sitec.com", 10], ["sitea.com", 745]]

Si necesitas un hash como resultado, puedes usar to_h (en Ruby 2.0+)

metrics.sort_by {|_key, value| value}.to_h
  # ==> {"siteb.com" => 9, "sitec.com" => 10, "sitea.com", 745}
 237
Author: Marc-André Lafortune,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-16 17:10:44

Dado que el valor es la última entrada, puede hacer:

metrics.sort_by(&:last)
 76
Author: shock_one,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-04 09:30:23

Ya contestado pero aún así. Cambie su código a:

metrics.sort {|a1,a2| a2[1].to_i <=> a1[1].to_i }

Convertido a cadenas en el camino o no, esto hará el trabajo.

 12
Author: dimitarvp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-30 09:10:49

Ese no es el comportamiento que estoy viendo:

irb(main):001:0> metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" =>
 10 }
=> {"siteb.com"=>9, "sitec.com"=>10, "sitea.com"=>745}
irb(main):002:0> metrics.sort {|a1,a2| a2[1]<=>a1[1]}
=> [["sitea.com", 745], ["sitec.com", 10], ["siteb.com", 9]]

¿Es posible que en algún lugar de la línea sus números se estén convirtiendo en cadenas? ¿Hay más código que no estés publicando?

 9
Author: Jacob Mattison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-29 19:01:15