In Ruby 1.9, Hash
ES sono ordinati, ma Hash#sort
restituisce ancora una Array
di Array
s. Immaginalo! Ciò implica che è possibile creare il proprio metodo di ordinamento su di esso.
class Hash
def sorted_hash(&block)
self.class[sort(&block)] # Hash[ [[key1, value1], [key2, value2]] ]
end
end
Hash
es sono non ordinati in Ruby 1.8. Se si desidera la compatibilità con Ruby 1.8, è possibile utilizzare lo OrderedHash
di ActiveSupport. Si comporta come un 1,9- Hash
, in modo da poter definire lo stesso metodo sorted_hash
su di esso:
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!
È necessario copiare il metodo sorted_hash
al codice, perché non esiste per impostazione predefinita!
Aggiornamento per profonda ordinamento: Se stai cercando di ordinare qualcosa altro che il tasto cancelletto, passare un blocco al metodo sorted_hash
(supponendo che l'attuazione dall'alto) come segue:
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", "..."=>"..."}}
Non ti ho preso. Ho cercato nel codice sorgente OrderedHash dei binari 2.3.2 e non vedo nulla riguardo ai metodi di ordinamento. – Dharam
@satynos: l'ho chiarito un po ', si spera. È necessario definire sorted_hash da soli, ma è davvero facile! Copia la mia implementazione, se vuoi. – molf
@molf: eccellente ... grazie per il feedback e l'aiuto per l'implementazione. Inoltre, se implemento il tuo metodo in classe Hash, funzionerà? o dovrebbe essere implementato in ActiveSupport :: OrderedHash? – Dharam