2009-06-11 12 views

Respuesta

11

En Ruby 1.9, es Hash están ordenados, pero todavía Hash#sort devuelve un Array de Array s. ¡Imagina eso! Implica que puedes construir tu propio método de clasificación encima.

class Hash 
    def sorted_hash(&block) 
    self.class[sort(&block)] # Hash[ [[key1, value1], [key2, value2]] ] 
    end 
end 

Hash es no clasificados en Ruby 1.8. Si desea la compatibilidad con Ruby 1.8, puede usar el OrderedHash de ActiveSupport. Se comporta como un 1.9- Hash, por lo que puede definir el mismo método sorted_hash en él:

class ActiveSupport::OrderedHash 
    def sorted_hash(&block) 
    self.class[sort(&block)] 
    end 
end 

hash = ActiveSupport::OrderedHash.new 
hash["b"] = "b" 
hash["a"] = "a" 
hash    #=> {"b"=>"b", "a"=>"a"} => unsorted 
hash.sorted_hash #=> {"a"=>"a", "b"=>"b"} => sorted! 

Tienes que copiar el método sorted_hash a su código, ya que no existe de forma predeterminada!

profunda actualización para la clasificación: Si usted está buscando para ordenar en otra cosa que la clave hash, pase un bloque con el método sorted_hash de la siguiente manera (suponiendo que la aplicación de la anterior):

hash = ActiveSupport::OrderedHash.new 
hash["a"] = { "attr" => "2", "..." => "..." } 
hash["b"] = { "attr" => "1", "..." => "..." } 

# Unsorted. 
hash 
    #=> {"a"=>{"attr"=>"2", "..."=>"..."}, "b"=>{"attr"=>"1", "..."=>"..."}} 

# Sort on the "attr" key. (Assuming every value is a Hash itself!) 
hash.sorted_hash { |a, b| a[1]["attr"] <=> b[1]["attr"] } 
    #=> {"b"=>{"attr"=>"1", "..."=>"..."}, "a"=>{"attr"=>"2", "..."=>"..."}} 
+0

No te entendí. Busqué en el código fuente OrderedHash de los rieles 2.3.2 y no veo nada en lo que respecta a los métodos de clasificación. – Dharam

+0

@satynos: Lo aclaré un poco, con suerte. ¡Tienes que definir sorted_hash tú mismo, pero es realmente fácil! Solo copie mi implementación si lo desea. – molf

+0

@molf: excelente ... gracias por los comentarios y la ayuda en la implementación. Además, si implemento su método en la clase Hash, ¿funcionará? o debería implementarse en ActiveSupport :: OrderedHash? – Dharam

8

Los hash son estructuras de datos fundamentalmente desordenadas; Hash#sort es, de hecho, lo que quiere. O eso, u ordena una lista de claves y luego úsala para enumerar cuándo es el momento de generar el hash, en lugar de enumerar directamente sobre el hash usando sus propios métodos.

+3

Técnicamente, los hashes están ordenados en Ruby 1.9. Pero creo que, en general, es mejor tratarlos como si no lo fueran, ya que no existe soporte para el reordenamiento. – Chuck

+0

Jim, ¿me puedes dar un ejemplo? – Dharam

+0

"Técnicamente, los hashes están ordenados en Ruby 1.9" ... esto me pone muy triste. ¡Se supone que un hash no tiene ningún orden implícito! Claro, entiendo querer ordenar algunas veces ... ¡pero crear un nombre diferente para esa estructura de datos! Grr. – Beska

Cuestiones relacionadas