How to Convert a Ruby Hash So That All of Its Keys Are Symbols

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



Leave a reply



Submit