Ruby JSON 解析更改哈希键
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7543779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ruby JSON parse changes Hash keys
提问by LanguagesNamedAfterCofee
Lets say I have this Hash:
假设我有这个哈希:
{
:info => [
{
:from => "Ryan Bates",
:message => "sup bra",
:time => "04:35 AM"
}
]
}
I can call the info array by doing hash[:info].
我可以通过执行调用 info 数组hash[:info]。
Now when I turn this into JSON (JSON.generate), and then parse it (JSON.parse), I get this hash:
现在,当我将其转换为 JSON (JSON.generate),然后解析它 (JSON.parse) 时,我得到了这个哈希值:
{
"info" => [
{
"from" => "Ryan Bates",
"message" => "sup bra",
"time" => "04:35 AM"
}
]
}
Now if I use hash[:info]it returns nil, but not if I use hash["info"].
现在,如果我使用hash[:info]它会返回nil,但如果我使用hash["info"].
Why is this? And is there anyway to fix this incompatibility (besides using string keys from the start)?
为什么是这样?有没有办法解决这种不兼容性(除了从一开始就使用字符串键)?
采纳答案by Lee Jarvis
In short, no. Think about it this way, storing symbols in JSON is the same as storing strings in JSON. So you cannot possibly distinguish between the two when it comes to parsing the JSON string. You can of course convert the string keys back into symbols, or in fact even build a class to interact with JSON which does this automagically, but I would recommend just using strings.
简而言之,没有。这样想想,在 JSON 中存储符号与在 JSON 中存储字符串是一样的。因此,在解析 JSON 字符串时,您不可能区分两者。您当然可以将字符串键转换回符号,或者实际上甚至可以构建一个类来与自动执行此操作的 JSON 交互,但我建议只使用字符串。
But, just for the sake of it, here are the answers to this question the previous times it's been asked:
但是,只是为了它,这里是以前被问到的这个问题的答案:
what is the best way to convert a json formatted key value pair to ruby hash with symbol as key?
将 json 格式的键值对转换为以符号为键的 ruby 哈希的最佳方法是什么?
ActiveSupport::JSON decode hash losing symbols
Or perhaps a HashWithIndifferentAccess
回答by wyattisimo
The JSON generator converts symbols to strings because JSON does not support symbols. Since JSON keys are all strings, parsing a JSON document will produce a Ruby hash with string keys by default.
JSON 生成器将符号转换为字符串,因为 JSON 不支持符号。由于 JSON 键都是字符串,默认情况下解析 JSON 文档将生成带有字符串键的 Ruby 哈希。
You can tell the parser to use symbols instead of strings by using the symbolize_namesoption.
您可以通过使用symbolize_names选项告诉解析器使用符号而不是字符串。
Example:
例子:
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"}]
Reference: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/json/rdoc/JSON.html#method-i-parse
参考:http: //www.ruby-doc.org/stdlib-1.9.3/libdoc/json/rdoc/JSON.html#method-i-parse
回答by aaron.v
I solved my similar issue with calling the with_indifferent_access method on it
我通过调用 with_indifferent_access 方法解决了我的类似问题
Here I have a json string and we can assign it to variable s
这里我有一个 json 字符串,我们可以将它分配给变量 s
s = "{\"foo\":{\"bar\":\"cool\"}}"
So now I can parse the data with the JSON class and assign it to h
所以现在我可以用 JSON 类解析数据并将其分配给 h
h = JSON.parse(s).with_indifferent_access
This will produce a hash that can accept a string or a symbol as the key
这将产生一个可以接受字符串或符号作为键的散列
h[:foo]["bar"]
#=> "cool"
回答by Jdfreefly
- Use ActiveSupport::JSON.decode, it will allow you to swap json parsers easier
- Use ActiveSupport::JSON.decode(my_json, symbolize_names: true)
- 使用 ActiveSupport::JSON.decode,它会让你更容易地交换 json 解析器
- 使用 ActiveSupport::JSON.decode(my_json, Symbol_names: true)
This will recursively symbolize all keys in the hash.
这将递归地符号化散列中的所有键。
(confirmed on ruby 2.0)
(在 ruby 2.0 上确认)
回答by Kathryn
It's possible to modify all the keys in a hash to convert them from a string to a symbol:
可以修改散列中的所有键以将它们从字符串转换为符号:
symbol_hash = Hash[obj.map{ |k,v| [k.to_sym, v] }]
puts symbol_hash[:info]
# => {"from"=>"Ryan Bates", "message"=>"sup bra", "time"=>"04:35 AM"}
Unfortunately that doesn't work for the hash nested inside the array. You can, however, write a little recursive method that converts all hash keys:
不幸的是,这对嵌套在数组中的哈希不起作用。但是,您可以编写一个小的递归方法来转换所有哈希键:
def symbolize_keys(obj)
#puts obj.class # Useful for debugging
return obj.collect { |a| symbolize_keys(a) } if obj.is_a?(Array)
return obj unless obj.is_a?(Hash)
return Hash[obj.map{ |k,v| [k.to_sym, symbolize_keys(v)] }]
end
symbol_hash = symbolize_keys(hash)
puts symbol_hash[:info]
# => {:from=>"Ryan Bates", :message=>"sup bra", :time=>"04:35 AM"}
回答by rails_id
You can't use that option like this
你不能像这样使用那个选项
ActiveSupport::JSON.decode(str_json, symbolize_names: true)
ActiveSupport::JSON.decode(str_json, symbolize_names: true)
In Rails 4.1 or later,
ActiveSupport::JSON.decodeno longer accepts an options hash for MultiJSON. MultiJSON reached its end of life and has been removed.
在 Rails 4.1 或更高版本中,
ActiveSupport::JSON.decode不再接受 MultiJSON 的选项哈希。MultiJSON 已达到其生命周期并已被删除。
You can use symbolize_keysto handle it. Warning: It works only for JSON strings parsed to hash.
您可以使用Symbolic_keys来处理它。警告:它仅适用于解析为哈希的 JSON 字符串。
ActiveSupport::JSON.decode(str_json).symbolize_keys

