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
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 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"}}
Unwanted symbol to string conversion of hash key
It may end up as a HashWithIndifferentAccess
if Rails somehow gets ahold of it, and that uses string keys internally. You might want to verify the class is the same:
assert_equal Hash, assigns(:my_hash).class
Parameters are always processed as the indifferent access kind of hash so you can retrieve using either string or symbol. If you're assigning this to your params hash on the get
or post
call, or you might be getting converted.
Another thing you can do is freeze it and see if anyone attempts to modify it because that should throw an exception:
@my_hash = { :my_key => :my_value }.freeze
Hash key access via symbol not string
Because 'key'
is a String
and :key
is a Symbol
- those are two different things in Ruby.
It can be somewhat confusing, because :'key'
, or 'key':
will also be a Symbol
To make it work, just access Hash
fields with a Symbol
, like:
if (auth[:user])
To convert String indexed Hash to Symbol indexed Hash, refer to this question:
Best way to convert strings to symbols in hash
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"}}
Turn a hash symbol to string and apply .ord method (for an offset)
If I understand your question correctly, I think this gives you want you want:
class Hash
def transpose_key(offset)
map do |key, value|
t = (key.to_s.ord - "a".ord + offset) % 26
[(t + "a".ord).chr.to_sym, value]
end.to_h
end
end
wrong_keys = { :a => "rope", :b => "knife", :x => "life-jacket", :z => "raft" }
puts wrong_keys.transpose_key(2)
# {:c=>"rope", :d=>"knife", :z=>"life-jacket", :b=>"raft"}
Array#to_h (v2.0+) is an alternative to the class method Hash::[] (v1.0+)for converting an array of two-element arrays to a hash:
a = [[1,2],[3,4]]
Hash[a] #=> {1=>2, 3=>4}
a.to_h #=> {1=>2, 3=>4}
If we removed .to_h
from the method we would find that the value returned by map
(to which to_h
is applied) is:
[[:c, "rope"], [:d, "knife"], [:z, "life-jacket"], [:b, "raft"]]
To use Hash#each_key, you could do this:
class Hash
def transpose_key(offset)
each_key.with_object({}) do |key,h|
t = (key.to_s.ord - "a".ord + offset) % 26
h[(t + "a".ord).chr.to_sym] = self[key]
end
end
end
puts wrong_keys.transpose_key(2)
# {:c=>"rope", :d=>"knife", :z=>"life-jacket", :b=>"raft"}
On reflection, I prefer the latter method.
Related Topics
Partial Haml Templating in Ruby Without Rails
How to Debug a Slow Rails App Boot Time
What's the Right Way to Implement Equality in Ruby
Is a System-Wide Install of Rvm a Bad Idea
Using Ruby Libraries and Gems with a Shoes App
Thread.Join Blocks the Main Thread
Passing Parameters to Erb View
When to Use Struct Instead of Hash in Ruby
What's the Best Way to Deploy a Jruby on Rails Application to Tomcat
Rails 4.0.1 on Heroku, Can't Create Database
Cannot Start Rails 4 Console on Production Server
Rails 4 Before_Action, Pass Parameters to Invoked Method
How to Ban/Block Users with Devise for Rails
What Is the Argument Against Using Before, Let and Subject in Rspec Tests
Why 6.84 - 3.6 == 3.2399999999999998