Ruby JSON解析改变了Hash密钥

Lan*_*fee 63 ruby hash json ruby-on-rails

让我们说我有这个哈希:

{
  :info => [
    {
        :from => "Ryan Bates",
        :message => "sup bra",
        :time => "04:35 AM"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我可以通过这样做来调用info数组hash[:info].

现在当我把它变成JSON(JSON.generate),然后解析它(JSON.parse)时,我得到这个哈希:

{
  "info" => [
    {
        "from" => "Ryan Bates",
        "message" => "sup bra",
        "time" => "04:35 AM"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我使用hash[:info]它返回nil,但如果我使用它hash["info"].

为什么是这样?无论如何都要修复这种不兼容性(除了从头开始使用字符串键)?

wya*_*imo 138

JSON生成器将符号转换为字符串,因为JSON不支持符号.由于JSON键都是字符串,因此解析JSON文档将默认生成带字符串键的Ruby哈希.

您可以通过使用该symbolize_names选项告诉解析器使用符号而不是字符串.

例:

original_hash = {:info => [{:from => "Ryan Bates", :message => "sup bra", :time => "04:35 AM"}]}
serialized = JSON.generate(original_hash)
new_hash = JSON.parse(serialized, {:symbolize_names => true})

new_hash[:info]
 #=> [{:from=>"Ryan Bates", :message=>"sup bra", :time=>"04:35 AM"}]
Run Code Online (Sandbox Code Playgroud)

参考:http://www.ruby-doc.org/stdlib-1.9.3/libdoc/json/rdoc/JSON.html#method-i-parse

  • @Boushley:不,它仍然是`symbolize_names`.我的回答引用了Ruby标准库附带的JSON引擎.您正在引用第三方gem. (11认同)

Lee*_*vis 23

简而言之,没有.以这种方式考虑,在JSON中存储符号与在JSON中存储字符串相同.因此,在解析JSON字符串时,您无法区分这两者.您当然可以将字符串键转换回符号,或者实际上甚至构建一个类来与JSON进行交互,自动执行此操作,但我建议您只使用字符串.

但是,只是为了它,以前是这个问题的答案:

将符号作为键将json格式的键值对转换为ruby hash的最佳方法是什么?

ActiveSupport :: JSON解码哈希丢失符号

或者也许是HashWithIndifferentAccess


小智 5

我在上面调用了with_indifferent_access方法解决了类似的问题

这里我有一个json字符串,我们可以将它分配给变量s

s = "{\"foo\":{\"bar\":\"cool\"}}"
Run Code Online (Sandbox Code Playgroud)

所以现在我可以用JSON类解析数据并将其分配给h

h = JSON.parse(s).with_indifferent_access
Run Code Online (Sandbox Code Playgroud)

这将生成一个可以接受字符串或符号作为键的哈希

h[:foo]["bar"]
  #=> "cool"
Run Code Online (Sandbox Code Playgroud)