How to Convert a JSON Formatted Key Value Pair to Ruby Hash with Symbol as Key

How to convert JSON response to hash, and extract specific key and value

You can use select to extract the expected key and value.
Please refer ruby select.

def specific_currency(currency)
@response_body ||= RestClient.get(@weather).body
@hash_response = JSON.parse(@response_body)['rates'].select { |element| element.to_s == currency }
end

Ruby JSON parse changes Hash keys

In short, no. Think about it this way, storing symbols in JSON is the same as storing strings in JSON. So you cannot possibly distinguish between the two when it comes to parsing the JSON string. You can of course convert the string keys back into symbols, or in fact even build a class to interact with JSON which does this automagically, but I would recommend just using strings.

But, just for the sake of it, here are the answers to this question the previous times it's been asked:

what is the best way to convert a json formatted key value pair to ruby hash with symbol as key?

ActiveSupport::JSON decode hash losing symbols

Or perhaps a HashWithIndifferentAccess

How to serialize/deserialize ruby hashes/structs with objects as keys to json

JSON only allows strings as object keys. For this reason to_s is called for all keys.

You'll have the following options to solve your issue:

  1. The best option is changing the data structure so it can properly be serialized to JSON.

  2. You'll have to handle the stringified key yourself. An Hash produces a perfectly valid Ruby syntax when converted to a string that can be converted using Kernel#eval like Andrey Deineko suggested in the comments.

    result = json.transform_keys { |key| eval(key) }
    # json.transform_keys(&method(:eval)) is the same as the above.

    The Hash#transform_keys method is relatively new (available since Ruby 2.5.0) and might currently not be in you development environment. You can replace this with a simple Enumerable#map if needed.

    result = json.map { |k, v| [eval(k), v] }.to_h

    Note: If the incoming JSON contains any user generated content I highly sugest you stay away from using eval since you might allow the user to execute code on your server.

How do I use symbols to access a JSON response with HTTParty?

Spoiler alert: best option is #3


Option 1: you can call .with_indifferent_access on the Hash to be able to access the values by using either 'link' or :link:

{'a' => 1}[:a]
# => nil
{'a' => 1}.with_indifferent_access[:a]
# => 1
{'a' => 1}.with_indifferent_access['a']
# => 1

Option 2: call .symbolize_keys (or .deep_symbolize_keys if you want to symbolize the nested keys too) on the hash to convert all keys to symbols:

hash = { 'name' => 'Rob', 'address' => { 'postal_code' => '92210' } }
hash.symbolize_keys
# => {:name=>"Rob", :address=>{'postal_code'=>'92210'}}
hash.deep_symbolize_keys
# => {:name=>"Rob", :address=>{:postal_code=>'92210'}}

Option 3: parse the JSON with the symbolize_names option set to true

JSON.parse(string, symbolize_names: true)

How to pass hash key value pairs as induvidual arguments?

you can use the double spat (**) on a hash in the method

  method(**test_hash)

Parse json key value pair in Rails to format the date

If you're iterating over a hash where the keys are symbols, then the error is telling you where and what's the problem. In order to parse a date, you must pass a string as argument, and as you haven't converted such object, then you're getting the error.

Try using to_s, to convert the symbol to string:

@data.each do |key, _|
puts Date.parse(key.to_s).strftime '%Y %m'
end

Note if you're inside a block, and you're not going to use the k variable you're creating, then you can avoid creating it, it won't be available outside the block. You're just printing the parsed date.

If you're not going to use the value block variable, then you can omit it.

As pointed @mu, you can omit the symbolize_names: true, and this way the keys will be strings, then, the conversion isn't needed:

require 'date'
require 'json'

request = '{
"data": {
"2017-11-22 00:22:26": "foo" ,
"2017-11-22 00:22:27": "bar"
}
}'
@data = JSON.parse(request)['data']
@data.each do |key, _|
puts Date.parse(key).strftime '%Y %m'
end

request is an approximation to your real data.

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


Related Topics



Leave a reply



Submit