ruby one liners to create hash

August 20, 2009 by
Filed under: technology 

Yesterday while going through one of my old programs, I found this written by me sometime back :

#begin magic
hash=Hash[*CGI.unescape(raw_text).split('&').map{|x| b=x.split("=");b.push(nil) if b.size==1;b}.flatten]
#end magic

To kill some of suspense let me disclose that raw_text looks like

"SUCCESS&mc_gross=10.00&protection_eligibility=Ineligible&payer_id=U7PPJJ4TSJ47E&tax=0.00&payment_date=09%3A45%3A30+Jul+10%2C+2009+PDT&payment_status=Pending"

, right it has been cut from paypal payment acknowledgment.

Above line if broken in parts reads better :

  unescaped_array= CGI.unescape(raw_text).split('&')
  unescaped_array= unescaped_array.collect{|x| b=x.split("=");b.push(nil) if b.size==1;b}
  flattened_array= unescaped_array.flatten
  hash= Hash[*flattened_array]

Let’s do individual steps in irb:

irb(main):009:0>unescaped_array= CGI.unescape(raw_text).split('&')    

=> ["SUCCESS", "mc_gross=10.00", "protection_eligibility=Ineligible", "payer_id=U7PPJJ4TSJ47E", "tax=0.00", "payment_date=09:45:30 Jul 10, 2009 PDT", "payment_status=Pending"]                                                                         

irb(main):013:0> unescaped_array= unescaped_array.map{|x| b=x.split("=");b.push(nil) if b.size==1;b}  

=> [["SUCCESS", nil], ["mc_gross", "10.00"],["protection_eligibility", "Ineligible"], ["payer_id", "U7PPJJ4TSJ47E"], ["tax", "0.00"], ["payment_date", "09:45:30 Jul 10, 2009 PDT"], ["payment_status", "Pending"]]                               

irb(main):014:0> flattened_array= unescaped_array.flatten     

=> ["SUCCESS", nil, "mc_gross", "10.00", "protection_eligibility", "Ineligible", "payer_id", "U7PPJJ4TSJ47E", "tax", "0.00", "payment_date", "09:45:30 Jul 10, 2009 PDT", "payment_status", "Pending"]
irb(main):015:0>
hash= Hash[*flattened_array]
=> {"tax"=>"0.00", "payment_status"=>"Pending", "payer_id"=>"U7PPJJ4TSJ47E", "mc_gross"=>"10.00", "SUCCESS"=>nil, "payment_date"=>"09:45:30 Jul 10, 2009 PDT", "protection_eligibility"=>"Ineligible"}

BTW, * is called splat operator in ruby

Another way to create hash from ‘array of pairs ‘ is to use inject :

hash= [[1,2],[3,4]].inject({}){|result,element| result[element.first]= result[element.last]; result}

There is one more way :) Write a loop, that I’ll leave as an exercise to the readers !!

Here is a bit unrelated use case of creating hash from arrays:

irb(main):005:0> [1,2,3,4,7,9].group_by{|x| x<5 ? :lesser : :greater}

=> {:lesser=>[1, 2, 3, 4], :greater=>[7, 9]}

You can do more things, basically result of the block is used as the key for that element in the resulting hash.

Comments

One Comment on ruby one liners to create hash

  1. ???????? on Thu, 21st Jan 2010 1:11 pm
  2. ??

Tell me what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!





  • Recent Posts