I have a Ruby hash which looks like:
{ \"id\" => \"123\", \"name\" => \"test\" }
I would like to convert it to:
{ :id
If you happen to be in Rails then you'll have symbolize_keys:
Return a new hash with all keys converted to symbols, as long as they respond to
to_sym
.
and symbolize_keys!
which does the same but operates in-place. So, if you're in Rails, you could:
hash.symbolize_keys!
If you want to recursively symbolize inner hashes then I think you'd have to do it yourself but with something like this:
def symbolize_keys_deep!(h)
h.keys.each do |k|
ks = k.to_sym
h[ks] = h.delete k
symbolize_keys_deep! h[ks] if h[ks].kind_of? Hash
end
end
You might want to play with the kind_of? Hash
to match your specific circumstances; using respond_to? :keys
might make more sense. And if you want to allow for keys that don't understand to_sym
, then:
def symbolize_keys_deep!(h)
h.keys.each do |k|
ks = k.respond_to?(:to_sym) ? k.to_sym : k
h[ks] = h.delete k # Preserve order even when k == ks
symbolize_keys_deep! h[ks] if h[ks].kind_of? Hash
end
end
Note that h[ks] = h.delete k
doesn't change the content of the Hash when k == ks
but it will preserve the order when you're using Ruby 1.9+. You could also use the [(key.to_sym rescue key) || key]
approach that Rails uses in their symbolize_keys!
but I think that's an abuse of the exception handling system.
The second symbolize_keys_deep!
turns this:
{ 'a' => 'b', 'c' => { 'd' => { 'e' => 'f' }, 'g' => 'h' }, ['i'] => 'j' }
into this:
{ :a => 'b', :c => { :d => { :e => 'f' }, :g => 'h' }, ['i'] => 'j' }
You could monkey patch either version of symbolize_keys_deep!
into Hash if you really wanted to but I generally stay away from monkey patching unless I have very good reasons to do it.