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:
The best option is changing the data structure so it can properly be serialized to JSON.
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
M Hartl's Ruby on Rails Tutorial Chapter 5 Custom Title on Home Page
Ruby Array to String Conversion
Tutorials or Screencasts on Building a Rest Web Service on Rails
How to Call Expire_Fragment from Rails Observer/Model
How to Redefine a Ruby Constant Without Warning
Jekyll on Windows: Pygments Not Working
How to Call a Super Class Method
How to Use Ruby's Readlines.Grep for Utf-16 Files
What Is Mattr_Accessor in a Rails Module
Ruby: Is There an Opposite of Include? for Ruby Arrays
Accessing Config from Application.Rb in Controller (Rails 3)
Relative Path to Your Project Directory