What\'s the (fastest/cleanest/straightforward) way to convert all keys in a hash from strings to symbols in Ruby?
This would be handy when parsing YAML.
params.symbolize_keys
will also work. This method turns hash keys into symbols and returns a new hash.
I really like the Mash gem.
you can do mash['key']
, or mash[:key]
, or mash.key
In case the reason you need to do this is because your data originally came from JSON, you could skip any of this parsing by just passing in the :symbolize_names
option upon ingesting JSON.
No Rails required and works with Ruby >1.9
JSON.parse(my_json, :symbolize_names => true)
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
symbols = [ ]
strings.each {|x| symbols.push(x.intern)}
So this is probably the most straightforward way to convert strings to symbols in your array(s) in Ruby. Make an array of strings then make a new variable and set the variable to an empty array. Then select each element in the first array you created with the ".each" method. Then use a block code to ".push" all of the elements in your new array and use ".intern or .to_sym" to convert all the elements to symbols.
Symbols are faster because they save more memory within your code and you can only use them once. Symbols are most commonly used for keys in hash which is great. I'm the not the best ruby programmer but this form of code helped me a lot.If anyone knows a better way please share and you can use this method for hash too!
This is not exactly a one-liner, but it turns all string keys into symbols, also the nested ones:
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
Starting on Psych 3.0 you can add the symbolize_names: option
Psych.load("---\n foo: bar")
# => {"foo"=>"bar"}
Psych.load("---\n foo: bar", symbolize_names: true)
# => {:foo=>"bar"}
Note: if you have a lower Psych version than 3.0 symbolize_names:
will be silently ignored.
My Ubuntu 18.04 includes it out of the box with ruby 2.5.1p57