Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the best way to convert a json formatted key value pair to ruby hash with symbol as key?

I am wondering what is the best way to convert a json formatted key value pair to ruby hash with symbol as key: example:

{ 'user': { 'name': 'foo', 'age': 40, 'location': { 'city' : 'bar', 'state': 'ca' } } } ==>  { :user=>{ :name => 'foo', :age =>'40', :location=>{ :city => 'bar', :state=>'ca' } } } 

Is there a helper method can do this?

like image 980
ez. Avatar asked Nov 13 '09 21:11

ez.


People also ask

What is JSON parse in Ruby?

JavaScript Object Notation, or JSON for short, is a simple and incredibly lightweight data exchange format. JSON is easy to write and read both for machines and humans. JSON is everywhere, and it is used to transfer structured data over the network with a major application in APIs.

How do you turn JSON into a Ruby object?

The most simplest way to convert a json into a Ruby object is using JSON. parse and OpenStruct class. If there are more subsequence keys after the response , the object. response will returns another instance of the OpenStruct class holding the subsequence methods as those subsequence keys.


2 Answers

using the json gem when parsing the json string you can pass in the symbolize_names option. See here: http://flori.github.com/json/doc/index.html (look under parse)

eg:

>> s ="{\"akey\":\"one\",\"bkey\":\"two\"}" >> JSON.parse(s,:symbolize_names => true) => {:akey=>"one", :bkey=>"two"}  
like image 127
jai Avatar answered Oct 10 '22 14:10

jai


Leventix, thank you for your answer.

The Marshal.load(Marshal.dump(h)) method probably has the most integrity of the various methods because it preserves the original key types recursively.

This is important in case you have a nested hash with a mix of string and symbol keys and you want to preserve that mix upon decode (for instance, this could happen if your hash contains your own custom objects in addition to highly complex/nested third-party objects whose keys you cannot manipulate/convert for whatever reason, like a project time constraint).

E.g.:

h = {       :youtube => {                     :search   => 'daffy',                 # nested symbol key                     'history' => ['goofy', 'mickey']      # nested string key                   }     } 

Method 1: JSON.parse - symbolizes all keys recursively => Does not preserve original mix

JSON.parse( h.to_json, {:symbolize_names => true} )   => { :youtube => { :search=> "daffy", :history => ["goofy", "mickey"] } }  

Method 2: ActiveSupport::JSON.decode - symbolizes top-level keys only => Does not preserve original mix

ActiveSupport::JSON.decode( ActiveSupport::JSON.encode(h) ).symbolize_keys   => { :youtube => { "search" => "daffy", "history" => ["goofy", "mickey"] } } 

Method 3: Marshal.load - preserves original string/symbol mix in the nested keys. PERFECT!

Marshal.load( Marshal.dump(h) )   => { :youtube => { :search => "daffy", "history" => ["goofy", "mickey"] } } 

Unless there is a drawback that I'm unaware of, I'd think Method 3 is the way to go.

Cheers

like image 33
frank Avatar answered Oct 10 '22 16:10

frank