В Ruby 1.9 Hash
сортируются, но Hash#sort
по-прежнему возвращает Array
из Array
с. Представь это! Это означает, что вы можете создать свой собственный метод сортировки поверх него.
class Hash
def sorted_hash(&block)
self.class[sort(&block)] # Hash[ [[key1, value1], [key2, value2]] ]
end
end
Hash
в Ruby 1.8 не отсортированы. Если вам нужна совместимость с Ruby 1.8, вы можете использовать ActiveSupport OrderedHash
. Он ведет себя как 1.9- Hash
, поэтому вы можете определить для него тот же метод sorted_hash
:
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!
Вы должны скопировать метод sorted_hash
в свой код, потому что он не существует по умолчанию!
Обновление для глубокой сортировки:
Если вы хотите отсортировать что-то еще, кроме ключа хеша, передайте блок методу sorted_hash
следующим образом (при условии реализации сверху):
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", "..."=>"..."}}