Zabba Zabba - 2 months ago 8
Ruby Question

How to transform "dot-notation" string keys in a Hash into a nested Hash?

How do I transform a Ruby Hash that looks like this:

{
:axis => [1,2],
:"coord.x" => [12,13],
:"coord.y" => [14,15],
}


Into this:

{
:axis => [1,2], #unchaged from input (ok)
:coord => #this has become a hash from coord.x and coord.y keys above
{
:x => [12,13]
:y => [14,15]
}
}


I have no idea where to start!

Answer

This code may need to be refactored but it works for the input you have given.

hash = { 
  :axis => [1,2], 
  "coord.x" => [12,13], 
  "coord.y" => [14,15], 
}

new_hash = {}
hash.each do |key, val|
  new_key, new_sub_key = key.to_s.split('.')
  new_key = new_key.to_sym
  unless new_sub_key.nil?
    new_sub_key = new_sub_key.to_sym
    new_hash[new_key] = {} if new_hash[new_key].nil?
    new_hash[new_key].merge!({new_sub_key => val})
  else
    new_hash.store(key, val)
  end
end

new_hash # => {:axis=>[1, 2], :coord=>{:x=>[12, 13], :y=>[14, 15]}}
Comments