在Ruby中,将哈希中的所有键从字符串转换为符号的(最快/最干净/直接)方法是什么?

这在解析YAML时非常方便。

my_hash = YAML.load_file('yml')

我希望能够使用:

my_hash[:key] 

而不是:

my_hash['key']

当前回答

如果你在使用Rails,这里有一个更好的方法:

params.symbolize_keys

最后。

如果你不是,那就抄袭他们的代码(链接中也有):

myhash.keys.each do |key|
  myhash[(key.to_sym rescue key) || key] = myhash.delete(key)
end

其他回答

这是一种深度象征物体的方法

def symbolize(obj)
    return obj.inject({}){|memo,(k,v)| memo[k.to_sym] =  symbolize(v); memo} if obj.is_a? Hash
    return obj.inject([]){|memo,v    | memo           << symbolize(v); memo} if obj.is_a? Array
    return obj
end

我真的很喜欢马什宝石。

你可以使用mash['key'],或者mash[:key],或者mash.key

如果你在使用Rails,这里有一个更好的方法:

params.symbolize_keys

最后。

如果你不是,那就抄袭他们的代码(链接中也有):

myhash.keys.each do |key|
  myhash[(key.to_sym rescue key) || key] = myhash.delete(key)
end

对于Ruby中YAML的特定情况,如果键以':'开头,它们将被自动作为符号存储。

require 'yaml'
require 'pp'
yaml_str = "
connections:
  - host: host1.example.com
    port: 10000
  - host: host2.example.com
    port: 20000
"
yaml_sym = "
:connections:
  - :host: host1.example.com
    :port: 10000
  - :host: host2.example.com
    :port: 20000
"
pp yaml_str = YAML.load(yaml_str)
puts yaml_str.keys.first.class
pp yaml_sym = YAML.load(yaml_sym)
puts yaml_sym.keys.first.class

输出:

#  /opt/ruby-1.8.6-p287/bin/ruby ~/test.rb
{"connections"=>
  [{"port"=>10000, "host"=>"host1.example.com"},
   {"port"=>20000, "host"=>"host2.example.com"}]}
String
{:connections=>
  [{:port=>10000, :host=>"host1.example.com"},
   {:port=>20000, :host=>"host2.example.com"}]}
Symbol

如果您需要这样做的原因是因为您的数据最初来自JSON,那么您可以跳过任何解析,只需在摄取JSON时传入:symbolize_names选项即可。

不需要Rails和工作与Ruby >1.9

JSON.parse(my_json, :symbolize_names => true)