Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create new hashes grouped by common key value in Ruby

Tags:

ruby

hash

Say I have a Hash that looks like this in Ruby:

{ :ie0 => "Hi",    :ex0 => "Hey",       :eg0 => "Howdy", 
  :ie1 => "Hello", :ex1 => "Greetings", :eg1 => "Good day"}

What is a good way to turn that into something like:

{ "0" => 
    { 
        "ie" => "Hi", "ex" => "Hey", "eg" => "Howdy"
    },
  "1" => 
    {
        "ie" => "Hello", "ex" => "Greetings", "eg" => "Good day"
    }
}
like image 705
tvalent2 Avatar asked Oct 05 '13 02:10

tvalent2


1 Answers

You asked for a good way to do it, so the answer is: a way that you or a co-worker can understand and maintain six months from now.

First, you want a Hash with autovivification because you're creating a nested hash structure. This is a very useful coding pattern which will simplify your application code:

# Copied & pasted from the question
old_hash = { :ie0 => "Hi", :ex0 => "Hey", :eg0 => "Howdy", :ie1 => "Hello", :ex1 => "Greetings", :eg1 => "Good day"}

# Auto-vivify
new_hash = Hash.new { |h, k| h[k] = { } }

Then, you can loop through your existing keys in this simple style, breaking out the parts of each key, and using them to save the value in the new hash:

old_hash.each_pair do |key, value|
  key =~ /^(..)(.)$/               # Make a regex group for each string to parse
  new_hash[$2][$1] = value         # The regex groups become the new hash keys
end

puts new_hash

I get this output:

{"0"=>{"ie"=>"Hi", "ex"=>"Hey", "eg"=>"Howdy"}, "1"=>{"ie"=>"Hello", "ex"=>"Greetings", "eg"=>"Good day"}}
like image 109
Dogweather Avatar answered Nov 15 '22 08:11

Dogweather