How to Change Hash Keys from 'Symbol's to 'String'S

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



Leave a reply



Submit