在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
其他回答
参数个数。Symbolize_keys也可以工作。这个方法将哈希键转换为符号并返回一个新的哈希值。
类似于前面的解决方案,但写得有点不同。
This allows for a hash that is nested and/or has arrays. Get conversion of keys to a string as a bonus. Code does not mutate the hash been passed in. module HashUtils def symbolize_keys(hash) transformer_function = ->(key) { key.to_sym } transform_keys(hash, transformer_function) end def stringify_keys(hash) transformer_function = ->(key) { key.to_s } transform_keys(hash, transformer_function) end def transform_keys(obj, transformer_function) case obj when Array obj.map{|value| transform_keys(value, transformer_function)} when Hash obj.each_with_object({}) do |(key, value), hash| hash[transformer_function.call(key)] = transform_keys(value, transformer_function) end else obj end end end
这是为那些使用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也是递归包含的散列 返回符号化的哈希值 工作到位!
这并不完全是一行程序,但是它将所有字符串键转换为符号,包括嵌套的符号:
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
在Rails中,你可以使用:
{'g'=> 'a', 2 => {'v' => 'b', 'x' => { 'z' => 'c'}}}.deep_symbolize_keys!
转换:
{:g=>"a", 2=>{:v=>"b", :x=>{:z=>"c"}}}