method
deep_symbolize_keys
v7.2.3 -
Show latest stable
- Class:
Hash
deep_symbolize_keys()public
Returns a new hash with all keys converted to symbols, as long as they respond to to_sym. This includes the keys from the root hash and from all nested hashes and arrays.
hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } } hash.deep_symbolize_keys # => {:person=>{:name=>"Rob", :age=>"28"}}
2Notes
Does not symbolize hashes in nested arrays
If you have a nested structure containing arrays of hashes, you still need to do that on your own, eg.
module SymbolizeHelper
def symbolize_recursive(hash)
{}.tap do |h|
hash.each { |key, value| h[key.to_sym] = map_value(value) }
end
end
def map_value(thing)
case thing
when Hash
symbolize_recursive(thing)
when Array
thing.map { |v| map_value(v) }
else
thing
end
end
end
Or, if you want to get really fancy with Ruby refinements (YMMV), one could do
module SymbolizeHelper
extend self
def symbolize_recursive(hash)
{}.tap do |h|
hash.each { |key, value| h[key.to_sym] = transform(value) }
end
end
private
def transform(thing)
case thing
when Hash; symbolize_recursive(thing)
when Array; thing.map { |v| transform(v) }
else; thing
end
end
refine Hash do
def deep_symbolize_keys
SymbolizeHelper.symbolize_recursive(self)
end
end
end
And later say
using SymbolizeHelper # augmented Hash#deep_symbolize_keys is now available
Works even on nested structures
@EdvardM added a note years ago saying this does not symbolize the keys of deeply nested hashes, which may have been the case for whatever version of ruby was available at the time, but in 4+, it definitely does work as described:
hash = {"a" => :a, "b" => {z: [[{"c" => 3}, {"c" => 4}], []]}}
hash.deep_symbolize_keys
=> {:a=>:a, :b=>{:z=>[[{:c=>3}, {:c=>4}], []]}}