web-dev-qa-db-ja.com

RubyでJSONオブジェクトを作成する方法

RubyでJSONファイルを作成しています。 JSONファイル内にオブジェクト「会社」を作成する必要があります。

期待される結果:

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

私が得ているもの:

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

私のコード:

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

問題の核は、配列ではなくJSON文字列の配列を作成し、そのJSONを作成することです。の代わりに:

companies_json = []

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

行う:

companies = []

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

companies_json = companies.to_json
11
Phrogz

@Phrogzには正しい答えがあります。これは、何が起こっているのかについてもう少し説明するためです。

require 'json'

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

これがJSONシリアル化ハッシュの外観です。これは、キーをラップするエスケープされた引用符を含む文字列で、:キーと値のペアを区切る。 JSONは常に配列、"[...]"、またはハッシュ、"{...}"、およびいずれの場合も文字列です。それこそが、シリアライズとJSONの機能です。

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

これは、JSONシリアル化されたハッシュを含む配列です。これがあなたがしていることです。文字列ではなく配列であるため、正しくシリアル化されていないことがわかります。周囲の[...]outside引用符ですが、JSONでは引用符の中にあります:

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

次へ...

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

それはハッシュのシリアル化された配列です。この場合、これは単一のハッシュですが、この例では十分です。これは、シリアライズ後の文字列です。これは、配列[...]は、insideを囲む引用符です。


このことを本当に理解したい場合は、 JSONホームページ とRubyの [〜#〜] json [〜#〜 ][〜#〜] yaml [〜#〜] および Psych ドキュメント。 JSONはほぼYAML のサブセットであるため、YAMLとPsychがそれを実装する方法を知ることは本当にとして役立ちますJSON、YAML、およびインターネットの使用に移行します。

「Ferインスタンス」:

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'

ちょっとあなたの心を吹きますよね?

8
the Tin Man