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

这在解析YAML时非常方便。

my_hash = YAML.load_file('yml')

我希望能够使用:

my_hash[:key] 

而不是:

my_hash['key']

当前回答

会像下面这样工作吗?

new_hash = Hash.new
my_hash.each { |k, v| new_hash[k.to_sym] = v }

它会复制哈希值,但大多数时候你不会在意。可能有一种不复制所有数据的方法。

其他回答

我真的很喜欢马什宝石。

你可以使用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

Symbolize_keys递归为任何哈希:

class Hash
  def symbolize_keys
    self.is_a?(Hash) ? Hash[ self.map { |k,v| [k.respond_to?(:to_sym) ? k.to_sym : k, v.is_a?(Hash) ? v.symbolize_keys : v] } ] : self
  end
end

如果你使用的是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

这并不完全是一行程序,但是它将所有字符串键转换为符号,包括嵌套的符号:

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