我有以下哈希:
user = {
'user' => {
'title' => {'weight' => 1, .... }
'body' => {'weight' => 4, ....}
....
....
}
}
是否可以让用户按其子哈希的权重键排序?
我查看了Hash.sort,但它看起来像是返回数组而不是我原来的哈希值。
答案 0 :(得分:11)
在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", "..."=>"..."}}
答案 1 :(得分:8)
哈希基本上是未排序的数据结构; Hash#sort
确实是你想要的。要么是这样,要么对键列表进行排序,然后使用它来枚举何时输出哈希值,而不是使用自己的方法直接枚举哈希值。