在Ruby中,将哈希中的所有键从字符串转换为符号的(最快/最干净/直接)方法是什么?
这在解析YAML时非常方便。
my_hash = YAML.load_file('yml')
我希望能够使用:
my_hash[:key]
而不是:
my_hash['key']
在Ruby中,将哈希中的所有键从字符串转换为符号的(最快/最干净/直接)方法是什么?
这在解析YAML时非常方便。
my_hash = YAML.load_file('yml')
我希望能够使用:
my_hash[:key]
而不是:
my_hash['key']
当前回答
@igorsales answer的修改
class Object
def deep_symbolize_keys
return self.inject({}){|memo,(k,v)| memo[k.to_sym] = v.deep_symbolize_keys; memo} if self.is_a? Hash
return self.inject([]){|memo,v | memo << v.deep_symbolize_keys; memo} if self.is_a? Array
return self
end
end
其他回答
这并不完全是一行程序,但是它将所有字符串键转换为符号,包括嵌套的符号:
def recursive_symbolize_keys(my_hash)
case my_hash
when Hash
Hash[
my_hash.map do |key, value|
[ key.respond_to?(:to_sym) ? key.to_sym : key, recursive_symbolize_keys(value) ]
end
]
when Enumerable
my_hash.map { |value| recursive_symbolize_keys(value) }
else
my_hash
end
end
更短的一行代码:
my_hash.inject({}){|h,(k,v)| h.merge({ k.to_sym => v}) }
从Ruby 2.5.0开始,你可以使用哈希#transform_keys或哈希#transform_keys!
{'a' => 1, 'b' => 2}.transform_keys(&:to_sym) #=> {:a => 1, :b => 2}
如果你使用的是Rails,这就简单多了——你可以使用HashWithIndifferentAccess,并以字符串和符号的形式访问键:
my_hash.with_indifferent_access
参见:
http://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html
或者你可以使用很棒的“Facets of Ruby”Gem,它包含了很多对Ruby核心和标准库类的扩展。
require 'facets'
> {'some' => 'thing', 'foo' => 'bar'}.symbolize_keys
=> {:some=>"thing", :foo=>"bar}
参见: http://rubyworks.github.io/rubyfaux/?doc=http://rubyworks.github.io/facets/docs/facets-2.9.3/core.json#api-class-Hash
facet的Hash#deep_rekey也是一个不错的选择,特别是:
如果你在项目中发现了其他糖的用途, 如果您更喜欢代码可读性而不是神秘的一行程序。
示例:
require 'facets/hash/deep_rekey'
my_hash = YAML.load_file('yml').deep_rekey