如何在Ruby中创建JSON对象

时间:2016-10-16 16:15:56

标签: json ruby parsing

我正在用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

2 个答案:

答案 0 :(得分:11)

您的问题的核心是您正在创建一个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

答案 1 :(得分:8)

@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序列化哈希的数组,这正是您正在做的事情。你可以告诉它没有正确序列化,因为它是一个数组,而不是一个字符串。周围的[...] 之外的引号中,而在JSON中它们在引号内:

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

继续......

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

这是一个序列化的哈希数组。在这种情况下,它只是一个哈希,但对于这个例子来说已经足够了。序列化后它是一个字符串,你可以告诉它,因为数组[...] 里面周围的引号。

如果您真的想了解这些内容,我强烈建议您阅读JSON home page以及Ruby的JSONYAMLPsych文档。 JSON is nearly a subset of YAML,所以当你开始使用JSON,YAML和互联网时,了解YAML以及Psych如何实现它是非常非常有用的。

&#34; Fer实例&#34;:

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'

有点打击你的想法不是吗?