How would I reverse the elements in the hash, keeping the same values and keys, but reversing their order in the hash.
Like so:
{ \"4\" => \"happiness
if need:
hash = {:a => :x, :b => :y, :c => :y, :d => :z}
to:
{:x => [:a], :y => [:b, c], :z => [:d] }
can:
h={};hash.to_a.each{|e|h[e[1]]||=[];h[e[1]]<<e[0]};h
h = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
p Hash[h.reverse_each.map{|e| e}]
#=> {"1"=>"spider", "lala"=>"54", "10"=>"cool", "4"=>"happiness"}
But this leaves a bad taste (just like the other answers, which work fine just like this one). If you have to do this, it could be an indication that a Hash was not the best choice.
Alternatively, you can use reduce
and merge
to add the item to the front of a new hash:
hash = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
hash.reduce({}){ |memo, object| Hash[*object].merge(memo) }
but, that's crazy :D
In Ruby 2.1+ you can combine reverse_each and to_h:
{foo: 1, bar: 2}.reverse_each.to_h
#=> {:bar=>2, :foo=>1}
You could convert the Hash to an Array, reverse that, and then convert it back to a Hash:
reversed_h = Hash[h.to_a.reverse]
Hash#to_a gives you an array of arrays, the inner arrays are simple [key,value]
pairs, then you reverse that array using Array#reverse, and Hash[] converts the [key,value]
pairs back into a Hash.
Ruby 2.1 adds an Array#to_h method so you can now say:
reversed_h = h.to_a.reverse.to_h
hash = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
reversed_hash = Hash[hash.to_a.reverse]