Ever had a hash which contained strings as keys and needed symbols instead? I do: From a REXML::Document I created a hash. Unfortunately, the keys were all strings and I needed them to be symbols at some other point in the app. Thank god, Ruby is capable of extending any object “on the fly”. So, I wrote a simple extension to Hash, which you might find useful as well:
class Hash #take keys of hash and transform those to a symbols def self.transform_keys_to_symbols(value) return value if not value.is_a?(Hash) hash = value.inject({}){|memo,(k,v)| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); memo} return hash end end
Usage is:
a = { "key" => 123, "inner_hash" => { "another_key" => "blabla" }} Hash.transform_keys_to_symbols(a) #returns a = { :key => 123, :inner_hash => { :another_key => "blabla" }}
Thank you!
Exactly what I was looking for!
You have a spelling error at Hash.transform_keys_to_symbol(v);
Thanks, Rick. I corrected it.
I know this was a long time ago, but refactored:
class Hash
#take keys of hash and transform those to a symbols
def self.transform_keys_to_symbols(value)
return value unless value.is_a?(Hash)
value.inject({}){|memo,(k,v)| memo[k.to_sym] = Hash.transform_keys_to_symbols(v); memo}
end
end
this will handle nested objects, but not a nested array of objects.
This should handle nested objects if they are arrays. I also put it in its own function instead of extending or monkey patching the Hash object.
def transform_keys_to_symbols(value)
if value.is_a?(Array)
array = value.map{|x| x.is_a?(Hash) || x.is_a?(Array) ? transform_keys_to_symbols(x) : x}
return array
end
if value.is_a?(Hash)
hash = value.inject({}){|memo,(k,v)| memo[k.to_sym] = transform_keys_to_symbols(v); memo}
return hash
end
return value
end
If time is money you’ve made me a weliahter woman.