33

同じ値とキーを維持しながら、ハッシュ内の要素を逆にする方法を教えてください。ただし、ハッシュ内の要素の順序を逆にします。

そのようです:

{ "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }

そしてそれを次のように変換します:

{ "1" => "spider", "lala" => "54", "10" => "cool", "4" => "happiness" }

または、eachハッシュの最初の要素ではなく、最後の要素から始めて、ループを逆方向に実行することもできますか?

4

9 に答える 9

68

ハッシュを配列に変換し、それを逆にしてから、ハッシュに戻すことができます。

reversed_h = Hash[h.to_a.reverse]

Hash#to_a配列の配列を提供します。内側の配列は単純な[key,value]ペアです。次に、を使用してその配列を逆にし、ペアをハッシュにArray#reverse変換Hash[]し直します。[key,value]

Ruby 2.1はメソッドを追加するArray#to_hので、次のように言うことができます。

reversed_h = h.to_a.reverse.to_h
于 2012-06-03T22:21:55.447 に答える
11

reverse_eachRuby 2.1以降では、以下を組み合わせることができますto_h

{foo: 1, bar: 2}.reverse_each.to_h
#=> {:bar=>2, :foo=>1}
于 2015-08-16T10:10:20.070 に答える
4
hash = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
reversed_hash = Hash[hash.to_a.reverse]
于 2012-06-03T22:22:10.860 に答える
4
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"}

しかし、これは悪い味を残します(他の答えと同じように、これと同じようにうまく機能します)。これを行う必要がある場合は、ハッシュが最良の選択ではなかったことを示している可能性があります。

于 2012-06-03T23:05:47.283 に答える
4

hash.map(&:reverse).to_h純粋なルビーでは、またはによってそれを行うことができますhash.reverse_each.to_h

Railsでは、次の方法で実行できますhash.invert

于 2018-06-27T13:34:43.140 に答える
1

または、とを使用reducemergeて、新しいハッシュの前にアイテムを追加することもできます。

hash = { "4" => "happiness", "10" => "cool", "lala" => "54", "1" => "spider" }
hash.reduce({}){ |memo, object| Hash[*object].merge(memo) }

しかし、それはクレイジーです:D

于 2012-06-03T22:42:31.043 に答える
1
reversed_h = Hash[h.to_a.collect(&:reverse)]
于 2013-04-16T02:32:30.933 に答える
0

Ruby 1.8.7では、ハッシュ内の要素の順序は私たちの管理下にないことが文書化されているため、上記のメソッドはいずれも機能しません。Ruby 1.9.3では、物事は機能し、他の回答が依存する方法で文書化されています。

$ irb1.8
h = {"4" => "happiness"、 "10" => "cool"、 "lala" => "54"、 "1" => "spider"}
ハッシュ[h.to_a()。reverse()]
=> {"lala" => "54"、 "1" => "スパイダー"、 "10" => "クール"、 "4"=>"幸福"}
終了する
$ irb1.9.1
h = {"4" => "happiness"、 "10" => "cool"、 "lala" => "54"、 "1" => "spider"}
ハッシュ[h.to_a()。reverse()]
=> {"1" => "スパイダー"、"ララ"=>"54"、 "10" => "クール"、 "4"=>"幸せ"}

Ruby 1.8.7の方法は私にとって非常にしっかりと根付いていたので、私はかなり長い間質問を誤解していました。私はそれがHash#invertへの方法を要求したと思いました:すなわち、範囲がドメインにマップされるようにハッシュを変換します。そのメソッドは重複を破棄します。LuísRamalhoはそうではない方法を提案しますが、それは少し不格好です。これは少し短いです:

$ irb
def invertWithDuplicates(original)
  reverse = Hash.new(){|ハッシュ、キー| hash [key] = []; }
  original.each_pair(){|キー、値| reverse [value] .push(key); }
  逆を返す
終わり
h = {"4" => "幸せ"、 "10" => "クール"、"ララ"=>"54"、 "1"=>​​"クール"}
invertWithDuplicates(h)
=> {"happiness" => ["4"]、 "cool" => ["1"、 "10"]、 "54" => ["lala"]}

OPの意図したトピックから逸​​脱して申し訳ありませんが、これは投稿のタイトル「Rubyでハッシュを逆にする」に適合していることを提出します。

于 2012-12-01T00:49:39.550 に答える
0

必要なら:

hash = {:a => :x, :b => :y, :c => :y, :d => :z}

に:

{:x => [:a], :y => [:b, c], :z => [:d] }

できる:

h={};hash.to_a.each{|e|h[e[1]]||=[];h[e[1]]<<e[0]};h
于 2019-02-07T19:24:29.693 に答える