web-dev-qa-db-fra.com

Comment créer un objet JSON dans Ruby

Je crée un fichier JSON avec Ruby. J'ai besoin de créer l'objet "sociétés" dans le fichier JSON.

Résultat attendu:

{"companies":[
    {\"label\":\"Wayfair \",\"values\":[54]},
    {\"label\":\"Move24 \",\"values\":[29]},
    {\"label\":\"Auto1 \",\"values\":[23]},
...
]}

Ce que j'obtiens:

[  
   "{\"label\":\"Wayfair \",\"values\":[54,54]}",
   "{\"label\":\"Move24 \",\"values\":[29,29]}",
   "{\"label\":\"GetYourGuide \",\"values\":[28,28]}",
   "{\"label\":\"Auto1.com \",\"values\":[20,20]}", ...
]

Mon 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
11
catch22

Le cœur de votre problème est que vous créez un tableau de chaînes JSON, au lieu d'un tableau, puis que vous créez ce JSON. Au lieu de:

companies_json = []

data_hash.each do |hash|
  companies_json << hash.to_json
end

faire:

companies = []

data_hash.each do |hash|
  companies << hash
end

companies_json = companies.to_json
11
Phrogz

@Phrogz a la bonne réponse. Ceci est pour fournir un peu plus d'explications sur ce qui se passe:

require 'json'

foo = {'a' => 1}
foo.to_json # => "{\"a\":1}"

Voilà à quoi ressemble un hachage sérialisé JSON. Il s'agit d'une chaîne contenant des guillemets d'échappement enveloppant la clé, avec : délimitant la paire clé/valeur. JSON est toujours un tableau, "[...]", ou un hachage, "{...}", et dans les deux cas, c'est une chaîne. C'est exactement ce que fait la sérialisation et comment fonctionne JSON.

[foo.to_json] # => ["{\"a\":1}"]
[foo.to_json].class # => Array

C'est un tableau contenant un hachage sérialisé JSON, ce que vous faites. Vous pouvez dire qu'il n'est pas sérialisé correctement car c'est un tableau, pas une chaîne. Les environs [...] sont en dehors des guillemets alors qu'en JSON ils sont à l'intérieur des guillemets:

[].to_json # => "[]"
{}.to_json # => "{}"

Continuons ...

[foo].to_json # => "[{\"a\":1}]"
[foo].to_json.class # => String

C'est un tableau sérialisé de hachages. Dans ce cas, il s'agit d'un seul hachage, mais cela suffit pour cet exemple. Il s'agit d'une chaîne après la sérialisation, ce que vous pouvez dire car le tableau [...] est à l'intérieur des guillemets environnants.


Si vous voulez vraiment comprendre ce genre de choses, je vous recommande fortement de lire à la fois page d'accueil JSON , ainsi que Ruby's JSON , YAML et Psych documentation. JSON est presque un sous-ensemble de YAML , donc connaître YAML et comment Psych l'implémente est vraiment utile lorsque vous commencez à travailler avec JSON, YAML et 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'

Ça vous souffle un peu, non?

8
the Tin Man