Reverse a hash in Ruby

后端 未结 9 1055
无人共我
无人共我 2021-02-06 23:22

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         


        
9条回答
  •  清酒与你
    2021-02-06 23:47

    In Ruby 1.8.7, the order of elements in a hash is documented to be not under our control, so none of the above methods work. In Ruby 1.9.3, things work and are documented in the way that the other answers rely upon.

    $ irb1.8
    h = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
    Hash[h.to_a().reverse()]
    => {"lala"=>"54", "1"=>"spider", "10"=>"cool", "4"=>"happiness"}
    quit
    $ irb1.9.1
    h = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
    Hash[h.to_a().reverse()]
    =>{"1"=>"spider", "lala"=>"54", "10"=>"cool", "4"=>"happiness"}
    

    The Ruby 1.8.7 way was ingrained so firmly for me that I misunderstood the question for quite some time. I thought it requested a way to Hash#invert: ie to transform the hash such that the range maps to the domain. That method discards duplicates. Luís Ramalho proffers a method that doesn't, but it's a bit clunky. This is a little shorter:

    $ irb
    def invertWithDuplicates(original)
      inverse = Hash.new() { |hash, key| hash[key] = []; }
      original.each_pair() { |key, value| inverse[value].push(key); }
      return inverse
    end
    h = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "cool" }
    invertWithDuplicates(h)
    => {"happiness"=>["4"], "cool"=>["1", "10"], "54"=>["lala"]}
    

    Sorry to drift away from the OP's intended topic, though I submit that this does fit the post's title "Reverse a hash in Ruby".

提交回复
热议问题