在 Ruby 中反转哈希
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10874356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reverse a hash in Ruby
提问by slyv
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", "10" => "cool", "lala" => "54", "1" => "spider" }
And convert that to:
并将其转换为:
{ "1" => "spider", "lala" => "54", "10" => "cool", "4" => "happiness" }
Or, perhaps I could run a eachloop backwards, starting from the last element in the hash, rather than the first?
或者,也许我可以each向后运行一个循环,从散列中的最后一个元素而不是第一个元素开始?
回答by mu is too short
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_agives 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.
Hash#to_a为您提供一个数组数组,内部数组是简单的[key,value]对,然后您使用 反转该数组Array#reverse,Hash[]并将这些[key,value]对转换回哈希。
Ruby 2.1 adds an Array#to_hmethod so you can now say:
Ruby 2.1 添加了一个Array#to_h方法,因此您现在可以说:
reversed_h = h.to_a.reverse.to_h
回答by Stefan
In Ruby 2.1+ you can combine reverse_eachand to_h:
在 Ruby 2.1+ 中,您可以组合reverse_each和to_h:
{foo: 1, bar: 2}.reverse_each.to_h
#=> {:bar=>2, :foo=>1}
回答by aromero
hash = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
reversed_hash = Hash[hash.to_a.reverse]
回答by steenslag
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.
但这留下了不好的味道(就像其他答案一样,就像这个答案一样工作正常)。如果您必须这样做,则可能表明哈希不是最佳选择。
回答by khaled_gomaa
In pure ruby, you can do it by hash.map(&:reverse).to_hor hash.reverse_each.to_h
在纯红宝石中,您可以通过hash.map(&:reverse).to_h或hash.reverse_each.to_h
In rails, you can do it by hash.invert
在 Rails 中,你可以通过 hash.invert
回答by Minqi Pan
reversed_h = Hash[h.to_a.collect(&:reverse)]
回答by dmitryck
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
回答by Martin Dorey
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.
在Ruby 1.8.7 中,散列中元素的顺序被记录为不受我们控制,因此上述方法均无效。在Ruby 1.9.3 中,事情以其他答案所依赖的方式工作和记录。
$ 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 methodthat doesn't, but it's a bit clunky. This is a little shorter:
Ruby 1.8.7 的方式对我来说根深蒂固,以至于我误解了这个问题很长一段时间。我认为它需要一种Hash#invert 的方法:即转换哈希,使范围映射到域。该方法丢弃重复项。Luís Ramalho 提供了一种没有的方法,但它有点笨拙。这有点短:
$ 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".
很抱歉偏离了 OP 的预期主题,尽管我认为这确实符合帖子的标题“在 Ruby 中反转哈希”。
回答by Christopher Manning
Alternatively, you can use reduceand mergeto add the item to the front of a new hash:
或者,您可以使用reduce和merge将项目添加到新哈希的前面:
hash = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
hash.reduce({}){ |memo, object| Hash[*object].merge(memo) }
but, that's crazy :D
但是,这太疯狂了 :D

