Last active
September 2, 2020 08:50
-
-
Save Integralist/9503099 to your computer and use it in GitHub Desktop.
Convert Ruby Hash keys into symbols
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
hash = { 'foo' => 'bar' } | |
# Version 1 | |
hash = Hash[hash.map { |k, v| [k.to_sym, v] }] | |
# Version 2 | |
hash = hash.reduce({}) do |memo, (k, v)| | |
memo.tap { |m| m[k.to_sym] = v } | |
end | |
# Version 3 | |
hash = hash.reduce({}) do |memo, (k, v)| | |
memo.merge({ k.to_sym => v}) | |
end | |
# None of the above solutions work with a multi-level hash | |
# They only work on the first level: {:foo=>"bar", :level1=>{"level2"=>"baz"}} | |
# The following two variations solve the problem in the same way | |
multi_hash = { 'foo' => 'bar', 'level1' => { 'level2' => 'baz' } } | |
# Modify `Object` | |
class Object | |
def deep_symbolize_keys | |
return self.reduce({}) do |memo, (k, v)| | |
memo.tap { |m| m[k.to_sym] = v.deep_symbolize_keys } | |
end if self.is_a? Hash | |
return self.reduce([]) do |memo, v| | |
memo << v.deep_symbolize_keys; memo | |
end if self.is_a? Array | |
self | |
end | |
end | |
multi_hash = multi_hash.deep_symbolize_keys | |
# Standalone method | |
def symbolize(obj) | |
return obj.reduce({}) do |memo, (k, v)| | |
memo.tap { |m| m[k.to_sym] = symbolize(v) } | |
end if obj.is_a? Hash | |
return obj.reduce([]) do |memo, v| | |
memo << symbolize(v); memo | |
end if obj.is_a? Array | |
obj | |
end | |
multi_hash = symbolize(multi_hash) |
Thank you 👍
Sweet, thanks!
A little trick, using just the Ruby libraries:
hash = { 'foo' => 'bar' }
require 'json'
JSON.parse(hash.to_json, { symbolize_names: true })
With multi hash
multi_hash = { 'foo' => 'bar', 'level1' => { 'level2' => 'baz' } }
=> {"foo"=>"bar", "level1"=>{"level2"=>"baz"}}
JSON.parse(multi_hash.to_json, { symbolize_names: true })
=> {:foo=>"bar", :level1=>{:level2=>"baz"}}
Still easier if you use Rails: https://apidock.com/rails/Hash/symbolize_keys
Very nice approach @martinezcoder
Cool Gist!
@Integralist I would like to add deep_symbolize_keys method to nice_hash gem: https://github.com/MarioRuiz/nice_hash
Since it is yours.... feel free to add it to the Hash class on https://github.com/MarioRuiz/nice_hash/blob/master/lib/nice/hash/add_to_ruby.rb
Or if you prefer it I can do it and name you in the code.
awesome!! @martinezcoder
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks. I hadn't known about .tap until seeing this example. Handy. I put together a slightly different version of the standalone method to clarify (for myself) the algorithm.