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

这在解析YAML时非常方便。

my_hash = YAML.load_file('yml')

我希望能够使用:

my_hash[:key] 

而不是:

my_hash['key']

当前回答

facet的Hash#deep_rekey也是一个不错的选择,特别是:

如果你在项目中发现了其他糖的用途, 如果您更喜欢代码可读性而不是神秘的一行程序。

示例:

require 'facets/hash/deep_rekey'
my_hash = YAML.load_file('yml').deep_rekey

其他回答

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

http://api.rubyonrails.org/classes/Hash.html#method-i-symbolize_keys

hash = { 'name' => 'Rob', 'age' => '28' }
hash.symbolize_keys
# => { name: "Rob", age: "28" }

从Psych 3.0开始,你可以添加symbolize_names:选项

心理。加载("——\n foo: bar") # => {"foo"=>"bar"}

心理。加载("——\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}

注意:如果你的Psych版本低于3.0,symbolize_names:将被默默地忽略。

我的Ubuntu 18.04自带ruby 2.5.1p57

这是为那些使用mruby并且没有定义任何symbolize_keys方法的人准备的:

class Hash
  def symbolize_keys!
    self.keys.each do |k|
      if self[k].is_a? Hash
        self[k].symbolize_keys!
      end
      if k.is_a? String
        raise RuntimeError, "Symbolizing key '#{k}' means overwrite some data (key :#{k} exists)" if self[k.to_sym]
        self[k.to_sym] = self[k]
        self.delete(k)
      end
    end
    return self
  end
end

方法:

仅表示字符串类型的键 如果符号化字符串意味着丢失一些信息(覆盖哈希的一部分)将引发RuntimeError symbolic也是递归包含的散列 返回符号化的哈希值 工作到位!

这里有很多答案,但rails函数的一个方法是hash.symbolize_keys