How do I convert a Ruby hash so that all of its keys are symbols?
hash = {"apple" => "banana", "coconut" => "domino"}
Hash[hash.map{ |k, v| [k.to_sym, v] }]
#=> {:apple=>"banana", :coconut=>"domino"}
@mu is too short: Didn't see word "recursive", but if you insist (along with protection against non-existent to_sym
, just want to remind that in Ruby 1.8 1.to_sym == nil
, so playing with some key types can be misleading):
hash = {"a" => {"b" => "c"}, "d" => "e", Object.new => "g"}
s2s =
lambda do |h|
Hash === h ?
Hash[
h.map do |k, v|
[k.respond_to?(:to_sym) ? k.to_sym : k, s2s[v]]
end
] : h
end
s2s[hash] #=> {:d=>"e", #<Object:0x100396ee8>=>"g", :a=>{:b=>"c"}}
Best way to convert strings to symbols in hash
In Ruby >= 2.5 (docs) you can use:
my_hash.transform_keys(&:to_sym)
Using older Ruby version? Here is a one-liner that will copy the hash into a new one with the keys symbolized:
my_hash = my_hash.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
With Rails you can use:
my_hash.symbolize_keys
my_hash.deep_symbolize_keys
How do I convert a Ruby hash so that all of its keys are strings
In pure Ruby (without Rails), you can do this with a combination of Enumerable#map
and Array#to_h
:
hash = { id: 123, name: "test" }
hash.map{|key, v| [key.to_s, v] }.to_h
How to change hash keys from `Symbol`s to `String`s?
simply call stringify_keys
(or stringify_keys!
)
http://apidock.com/rails/Hash/stringify_keys
Swap hash keys with values and convert keys to symbols in Ruby?
You can do this:
Hash[periods.values.zip(periods.keys.map(&:to_sym))]
Or if you're using a version of Ruby where to_h
is available for arrays, you can do this:
periods.values.zip(periods.keys.map(&:to_sym)).to_h
What the two examples above do is make arrays of the keys and values of the original hash. Note that the string keys of the hash are mapped to symbols by passing to_sym
to map
as a Proc
:
periods.keys.map(&:to_sym)
# => [:q1, :q2, :q3, :q4, :h1, :h2]
periods.values
# => [0, 1, 2, 3, 4, 5]
Then it zips them up into an array of [value, key]
pairs, where each corresponding elements of values
is matched with its corresponding key in keys
:
periods.values.zip(periods.keys.map(&:to_sym))
# => [[0, :q1], [1, :q2], [2, :q3], [3, :q4], [4, :h1], [5, :h2]]
Then that array can be converted back into a hash using Hash[array]
or array.to_h
.
How to recursively convert keys of Ruby Hashes that are symbols to String
If you are using ActiveSupport
already or are open to using it, then deep_stringify_keys is what you're looking for.
hash = { person: { name: 'Rob', age: '28' } }
hash.deep_stringify_keys
# => {"person"=>{"name"=>"Rob", "age"=>"28"}}
Best way to convert strings to symbols in hash
In Ruby >= 2.5 (docs) you can use:
my_hash.transform_keys(&:to_sym)
Using older Ruby version? Here is a one-liner that will copy the hash into a new one with the keys symbolized:
my_hash = my_hash.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
With Rails you can use:
my_hash.symbolize_keys
my_hash.deep_symbolize_keys
Symbols used as Hash keys get converted to Strings when serialized
More than likely this has to do with the ORM you are using to provide the persistance layer for the model. You can probably wrap some_attr
with a method that returns it in the form of a HashWithIndifferentAccess
which you can then access with either strings or arrays. Since you are using Rails, this functionality can be activated by calling the with_indifferent_access
method on the Hash object. (If you have an array of Hash objects, you'll need to call it on each one of course) The method will return the same hash, but then symbol lookups will work.
From your code:
new_hash = MyMongoModel.last.some_attr.with_indifferent_access
new_hash[:a] # Will return the same as new_hash['a']
Hope this helps!
Related Topics
Best Way to Highlight Current Page in Rails 3? - Apply a CSS Class to Links Conditionally
Rails 3.1 Pipeline - Exclude JavaScript File
How to Run Ruby and Git Commands in One Place on Windows
Return Index of All Occurrences of a Character in a String in Ruby
What's the Point of Unary Plus Operator in Ruby
How to Install Rvm System Requirements Without Giving Sudo Access for Rvm User
Ruby on Rails "Invalid Byte Sequence in Utf-8" Due to Bot
Gem Install Error (Sass Compass)
Gem.Source_Index Is Deprecated, Use Specification. Should I Re-Install Gem or Rails
How to Validate Exits and Aborts in Rspec
Ruby: Dynamically Generate Attribute_Accessor
How to Debug in Rubymine 4.5 Using Ruby 1.9.3
Is There a Natural_Sort_By Method for Ruby
Call Controller from Rake Task