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

这在解析YAML时非常方便。

my_hash = YAML.load_file('yml')

我希望能够使用:

my_hash[:key] 

而不是:

my_hash['key']

当前回答

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

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

其他回答

如果你正在使用json,并且想要使用它作为哈希,在核心Ruby中你可以这样做:

json_obj = JSON.parse(json_str, symbolize_names: true)

symbolize_names:如果设置为true,将返回JSON对象中名称(键)的符号。否则返回字符串。字符串是默认的。

Doc: Json#解析symbolize_names

会像下面这样工作吗?

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

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

在ruby中,我发现这是最简单、最容易理解的将字符串键转换为符号的方法:

my_hash.keys.each { |key| my_hash[key.to_sym] = my_hash.delete(key)}

对于散列中的每个键,我们调用delete函数将其从散列中删除(delete也返回与被删除的键相关的值),并立即将其设置为符号化的键。

更短的一行代码:

my_hash.inject({}){|h,(k,v)| h.merge({ k.to_sym => v}) }
ruby-1.9.2-p180 :001 > h = {'aaa' => 1, 'bbb' => 2}
 => {"aaa"=>1, "bbb"=>2} 
ruby-1.9.2-p180 :002 > Hash[h.map{|a| [a.first.to_sym, a.last]}]
 => {:aaa=>1, :bbb=>2}