如果您碰巧在 Rails 中,那么您将拥有symbolize_keys:
只要响应to_sym,返回所有键都转换为符号的新哈希。
和symbolize_keys! 做同样的事情但就地操作。所以,如果你在 Rails 中,你可以:
hash.symbolize_keys!
如果你想递归地符号化内部哈希,那么我认为你必须自己做,但是用这样的东西:
def symbolize_keys_deep!(h)
h.keys.each do |k|
ks = k.to_sym
h[ks] = h.delete k
symbolize_keys_deep! h[ks] if h[ks].kind_of? Hash
end
end
您可能想使用kind_of? Hash 来匹配您的具体情况;使用respond_to? :keys 可能更有意义。如果你想允许不理解to_sym的键,那么:
def symbolize_keys_deep!(h)
h.keys.each do |k|
ks = k.respond_to?(:to_sym) ? k.to_sym : k
h[ks] = h.delete k # Preserve order even when k == ks
symbolize_keys_deep! h[ks] if h[ks].kind_of? Hash
end
end
请注意,h[ks] = h.delete k 不会在 k == ks 时更改哈希的内容,但在您使用 Ruby 1.9+ 时会保留顺序。您也可以使用 Rails 在其 symbolize_keys! 中使用的 [(key.to_sym rescue key) || key] 方法,但我认为这是对异常处理系统的滥用。
第二个symbolize_keys_deep! 变成这个:
{ 'a' => 'b', 'c' => { 'd' => { 'e' => 'f' }, 'g' => 'h' }, ['i'] => 'j' }
进入这个:
{ :a => 'b', :c => { :d => { :e => 'f' }, :g => 'h' }, ['i'] => 'j' }
如果您真的愿意,您可以将 symbolize_keys_deep! 的任一版本修改为 Hash,但除非我有充分的理由这样做,否则我通常不会进行修改。