Ruby JSONparsing修改哈希键

可以说我有这个哈希:

{ :info => [ { :from => "Ryan Bates", :message => "sup bra", :time => "04:35 AM" } ] } 

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

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

 { "info" => [ { "from" => "Ryan Bates", "message" => "sup bra", "time" => "04:35 AM" } ] } 

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

为什么是这样? 无论如何,解决这个不兼容(除了从一开始就使用string键)?

总之,没有。 这样想一下,在JSON中存储符号与在JSON中存储string是一样的。 所以在parsingJSONstring时,你不能区分这两者。 您当然可以将string键转换回符号,或者甚至build立一个类来与JSON进行交互,这是自动完成的,但我会build议使用string。

但是,正因为如此,以前这个问题的答案是这样的:

将json格式化的键值对转换为ruby哈希键的最好方法是什么?

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

或者也许是一个HashWithIndifferentAccess

JSON生成器将符号转换为string,因为JSON不支持符号。 由于JSON密钥都是string,因此parsingJSON文档将默认生成带有string键的Ruby哈希。

您可以通过使用symbolize_names选项来告诉parsing器使用符号而不是string。

例:

 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"}] 

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

我通过调用with_indifferent_access方法解决了类似的问题

在这里我有一个jsonstring,我们可以将其分配给variabless

 s = "{\"foo\":{\"bar\":\"cool\"}}" 

所以现在我可以使用JSON类来parsing数据并将其分配给h

 h = JSON.parse(s).with_indifferent_access 

这将产生一个可以接受string或符号作为键的散列

 h[:foo]["bar"] #=> "cool" 
  1. 使用ActiveSupport :: JSON.decode,它将允许您更容易地交换jsonparsing器
  2. 使用ActiveSupport :: JSON.decode(my_json,symbolize_names:true)

这将recursion地表示散列中的所有键。

(确认在ruby2.0)

可以修改散列中的所有键将它们从string转换为符号:

 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"} 

不幸的是,这对嵌套在数组中的哈希不起作用。 但是,您可以编写一个可以转换所有散列键的小recursion方法:

 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"} 

你不能像这样使用这个选项

ActiveSupport::JSON.decode(str_json, symbolize_names: true)

在Rails 4.1或更高版本中, ActiveSupport::JSON.decode不再接受MultiJSON的选项哈希。 MultiJSON达到了其生命的尽头,并已被删除。

你可以使用symbolize_keys来处理它。

 ActiveSupport::JSON.decode(str_json).symbolize_keys