How to convert JSON to a Ruby hash
What about the following snippet?
require 'json'
value = '{"val":"test","val1":"test1","val2":"test2"}'
puts JSON.parse(value) # => {"val"=>"test","val1"=>"test1","val2"=>"test2"}
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
Convert JSON into a Hash
Solved my issues using:
object = self.as_json.with_indifferent_access
# => allowing me to use a symbol key instead of a string
ok_vals = object[:values][:ok].as_json.gsub(/\=\>/, ':')
# => allowing to change json string '{"val1"=>"val1", "val2"=>"val2"}' to '{"val1":"val1", "val2":"val2"}'
ok_vals = JSON.parse(ok_vals)
# => which transform json string to hash {val1: "val1", val2: "val2"}
Feel free to make any suggestions to this code. Thanks for the help.
How can I convert a string in my JSON file into a Ruby hash?
I think something like this would help:
def media_url
tweet = self.object
JSON.parse(tweet.media[0].gsub('=>', ':'))["media_url"]
end
You need to replace =>
with :
in order for JSON.parse
to work
Or
To get the complete hash you can use a more generic method like media
:
def media
tweet = self.object
JSON.parse(tweet.media[0].gsub('=>', ':'))
end
How to convert JSON to a hash, search for and change a value
I understand your JSON may look like this:
"{\"features\":{\"additional-options\":true},\"values\":{\"lo-value\":34,\"hi-value\":554},\"persons\":[{\"name\":\"john\",\"member\":true,\"current\":false,\"sponsor\":\"pete\",\"profile\":\"\",\"credits\":[\"04\"],\"linked\":[\"philip\",\"guy\"],\"maptools\":[\"crossfit\",\"soccer\",\"running\"]},{\"name\":\"mary\",\"member\":true,\"current\":false,\"sponsor\":\"judy\",\"profile\":\"\",\"credits\":[\"all\"],\"activities\":[\"swimming\",\"cycling\",\"running\"]}],\"data_map\":[1122,3234]}"
I suggest using an OpenStruct to organize your data:
your_struct_name = JSON.parse(yourJson, object_class: OpenStruct)
Then you get all the things you want. For the operations you show:
#change_key(hash, "features.additional-options", false)
your_struct_name.features['additional-options'] = false
#this one above you set in this hash-like manner because of the '-' in the middle of the key. Otherwise you could just do your_struct_name.features.additional_options = false
#del_from_array(hash, "persons.name=mary.activities", "cycling")
your_struct_name.persons.last.activities.delete('swimming')
# or selecting by name:
your_struct_name.persons.select {|person| person.name == 'mary' }.first.activities.delete('swimming')
#add_to_array(hash, "persons.name=mary.activities", "hockey")
your_struct_name.persons.last.activities << 'hockey'
#del_key(hash, "data_map")
your_struct_name.delete_field('data_map')
#del_key(hash, persons.name=john.profile)
...
#del_key(hash, persons.name=mary.credits)
...
Then, after you make your changes, you can use:
your_struct_name.to_h.to_json
You can also use the method as_json
to get a structure very similar to what you showed on the question:
your_struct_name.as_json
OpenStruct
is very nice to deal with data that has a changing structure. If you have data that can be "modeled", has a name you can call, has some attributes you can predict, and even methods you will use for this data, I suggest you to create a Class to describe this data, its properties and attributes (it can even inherit from OpenStruct). Then work inside this Class domain, creating a layer of abstraction. This way your code gets a lot more robust and readable. Don't forget to create automatic tests! It saves you a lot of time.
The way you organize and abstract your data, and specially the way you name entities are things that have high impact on code quality.
For further reading see: Object and ActiveData.
Parsing JSON list object to Ruby hash
A JSON Array of Objects becomes a Ruby Array of Hashes. These Hashes can then contain more Arrays and so on.
If you want to access the Hashes, you need to iterate through the Array. If you want to access the groups you need to iterate again.
scripts = JSON.parse(json)
# Iterate through each script
scripts.each { |script|
# Print the script's name.
puts "Script: #{script["name"]}"
# Iterate through the script's groups.
groups = script["groups"]
groups.each { |group|
# Print each group's name.
puts "Group: #{group["name"]}"
}
}
How to convert a ruby hash object to JSON?
One of the numerous niceties of Ruby is the possibility to extend existing classes with your own methods. That's called "class reopening" or monkey-patching (the meaning of the latter can vary, though).
So, take a look here:
car = {:make => "bmw", :year => "2003"}
# => {:make=>"bmw", :year=>"2003"}
car.to_json
# NoMethodError: undefined method `to_json' for {:make=>"bmw", :year=>"2003"}:Hash
# from (irb):11
# from /usr/bin/irb:12:in `<main>'
require 'json'
# => true
car.to_json
# => "{"make":"bmw","year":"2003"}"
As you can see, requiring json
has magically brought method to_json
to our Hash
.
Convert JSON string to hash
It's most likely because this isn't valid JSON. Change your single quotes to double quotes, like so:
test = '[{"domain": "abc.com"}, {"domain": "def.com"}, {"domain": "ghi.com"}]'
An explanation can be found here, and you can validate your JSON here.
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
from json to a ruby hash?
You want JSON.parse
or JSON.load
:
def load_user_lib( filename )
JSON.parse( IO.read(filename) )
end
The key here is to use IO.read
as a simple way to load the JSON string from disk, so that it can be parsed. Or, if you have UTF-8 data in your file:
my_object = JSON.parse( IO.read(filename, encoding:'utf-8') )
I've linked to the JSON documentation above, so you should go read that for more details. But in summary:
json = my_object.to_json
— method on the specific object to create a JSON string.json = JSON.generate(my_object)
— create JSON string from object.JSON.dump(my_object, someIO)
— create a JSON string and write to a file.my_object = JSON.parse(json)
— create a Ruby object from a JSON string.my_object = JSON.load(someIO)
— create a Ruby object from a file.
Alternatively:
def load_user_lib( filename )
File.open( filename, "r" ) do |f|
JSON.load( f )
end
end
Note: I have used a "snake_case" name for the method corresponding to your "camelCase" saveUserLib
as this is the Ruby convention.
Related Topics
Rails with Ruby-Debugger Throw 'Symbol Not Found: _Ruby_Current_Thread (Loaderror)'
Where to Put Ruby Helper Methods for Rails Controllers
How to Install the Ruby Ri Documentation
How to Make Part of a Regular Expression Optional in Ruby
Always Getting 401 Unauthorized with New Install of Rails + Devise
How to Map/Collect with Index in Ruby
Rails - the System Cannot Find the Path Specified
How to Set Up Simple Http Authentication for a Ruby on Rails App on Heroku
What Are the Differences Between "Private", "Public", and "Protected Methods"
What Does the "$" Character Mean in Ruby
Rails Route to Username Instead of Id
Why Does Array.Slice Behave Differently for (Length, N)
Rails on Windows - Install Issue
Nokogiri Was Built Against Libxml Version 2.7.7, But Has Dynamically Loaded 2.7.3
Update Just One Gem with Bundler
How to Have Multiple Versions of Ruby and Rails, and Their Combinations on Windows