Reputation: 1252
I create a hash in ruby with integer keys and send it as a JSON response. This JSON is then parsed and the hash is converted back to ruby. The keys are now string literals.
I get it that JSON doesnt support integer keys but I came upon this method which basically parses the hash so that it has symbol keys.
JSON.parse(hash, {:symbolize_names => true})
Is there a similar function for obtaining back the original integer keys
a = {1 => 2}
a.keys
=> [1]
b = JSON.parse(JSON.generate(a))
b.keys
=> ["1"]
My hash is very complicated. The value itself is a hash which is supposed to have integer keys. There are multiple such levels of nesting
Upvotes: 8
Views: 4472
Reputation: 782
normal key transformation using built in method by passing required block
hash1 = {'1' => {'2' => 'val2', '3' => 'val3'}}
p hash1.transform_keys(&:to_i)
{1=>{"2"=>"val2", "3"=>"val3"}}
nested key transformation solution by passing required block
class Hash
def deep_transform_keys(&block)
result = {}
each do |key, value|
result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
end
result
end
end
hash1 = {'1' => {'2' => 'val2', '3' => 'val3'}}
p hash1.deep_transform_keys(&:to_i)
{1=>{2=>"val2", 3=>"val3"}}
Upvotes: 2
Reputation: 7714
Nothing in JSON as far as I know, but conversion is easy:
json_hash = {"1" => "2" }
integer_hash = Hash[json_hash.map{|k,v|[ k.to_i, v.to_i ]}]
=> {1 => 2}
So, we take all key & value from the initial hash (json_hash
), call to_i on them and get them in a new hash (integer_hash
).
Even nesting is not blocking. You could do this in a method:
def to_integer_keys(hash)
keys_values = hash.map do |k,v|
if(v.kind_of? Hash)
new_value = to_integer_keys(v) #it's a hash, let's call it again
else
new_value = v.to_i #it's a integer, let's convert
end
[k.to_i, new_value]
end
Hash[keys_values]
end
Upvotes: 7