I am creating a JSON file with Ruby. I need to create the object "companies" within the JSON file.
Expected result:
{"companies":[
{\"label\":\"Wayfair \",\"values\":[54]},
{\"label\":\"Move24 \",\"values\":[29]},
{\"label\":\"Auto1 \",\"values\":[23]},
...
]}
What I am getting:
[
"{\"label\":\"Wayfair \",\"values\":[54,54]}",
"{\"label\":\"Move24 \",\"values\":[29,29]}",
"{\"label\":\"GetYourGuide \",\"values\":[28,28]}",
"{\"label\":\"Auto1.com \",\"values\":[20,20]}", ...
]
My code:
data_hash = data_hash.map {|k,v| {label: k, values: v}}
companies_json = []
data_hash.each do |hash|
companies_json << hash.to_json
end
File.open('companies.json', 'w') do |f|
f << companies_json
end
JavaScript Object Notation (JSON)¶ ↑ JSON is a lightweight data-interchange format. A JSON value is one of the following: Double-quoted text: "foo" . Number: 1 , 1.0 , 2.0e2 .
The core of your problem is that you are creating an array of JSON strings, instead of an array and then making that JSON. Instead of:
companies_json = []
data_hash.each do |hash|
companies_json << hash.to_json
end
do:
companies = []
data_hash.each do |hash|
companies << hash
end
companies_json = companies.to_json
@Phrogz has the correct answer. This is to provide a bit more explanation of what's happening:
require 'json'
foo = {'a' => 1}
foo.to_json # => "{\"a\":1}"
That's what a JSON serialized hash looks like. It's a string containing escaped quotes wrapping the key, with :
delimiting the key and value pair. JSON is always an array, "[...]"
, or a hash, "{...}"
, and in either case it's a String. That's just what serializing does and how JSON works.
[foo.to_json] # => ["{\"a\":1}"]
[foo.to_json].class # => Array
That's an array containing a JSON serialized hash, which is what you're doing. You can tell it's not serialized correctly because it's an Array, not a String. The surrounding [...]
are outside the quotes whereas in JSON they're inside the quotes:
[].to_json # => "[]"
{}.to_json # => "{}"
Moving on...
[foo].to_json # => "[{\"a\":1}]"
[foo].to_json.class # => String
That's a serialized array of hashes. In this case it's a single hash, but it's sufficient for this example. It's a String after serializing, which you can tell because the array [...]
is inside the surrounding quotes.
If you really want to understand this stuff I highly recommend reading both the JSON home page, along with Ruby's JSON, YAML and Psych documentation. JSON is nearly a subset of YAML, so knowing YAML and how Psych implements it is really helpful as you move into working with JSON, YAML and the internet.
"Fer instance":
json_hash = '{"a":1}'
yaml_hash = "---\na: 1"
require 'yaml'
YAML.load(json_hash) # => {"a"=>1}
YAML.load(yaml_hash) # => {"a"=>1}
Psych.load(json_hash) # => {"a"=>1}
Psych.load(yaml_hash) # => {"a"=>1}
require 'json'
JSON[json_hash] # => {"a"=>1}
JSON[yaml_hash] # => JSON::ParserError: 743: unexpected token at '---\na: 1'
Kinda blows your mind doesn't it?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With