98

次のようなハッシュの配列があります。

 [{"testPARAM1"=>"testVAL1"}, {"testPARAM2"=>"testVAL2"}]

そして、これを次のような単一のハッシュにマップしようとしています:

{"testPARAM2"=>"testVAL2", "testPARAM1"=>"testVAL1"}

私はそれを使用してそれを達成しました

  par={}
  mitem["params"].each { |h| h.each {|k,v| par[k]=v} } 

しかし、これをより慣用的な方法で(できればローカル変数を使用せずに)行うことができるかどうか疑問に思っていました。

これどうやってするの?

4

5 に答える 5

173

あなたはあなたが望むものを作成Enumerable#reduceHash#merge、達成することができます。

input = [{"testPARAM1"=>"testVAL1"}, {"testPARAM2"=>"testVAL2"}]
input.reduce({}, :merge)
  is {"testPARAM2"=>"testVAL2", "testPARAM1"=>"testVAL1"}

配列の各要素の間にメソッド呼び出しを貼り付けるのと同じように、配列を削減します。

たとえば、[1, 2, 3].reduce(0, :+)と言っ0 + 1 + 2 + 3て与えるようなもの6です。

私たちの場合、似たようなことを行いますが、2 つのハッシュをマージするマージ関数を使用します。

[{:a => 1}, {:b => 2}, {:c => 3}].reduce({}, :merge)
  is {}.merge({:a => 1}.merge({:b => 2}.merge({:c => 3})))
  is {:a => 1, :b => 2, :c => 3}
于 2012-08-08T01:54:19.013 に答える
55

どうですか:

h = [{"testPARAM1"=>"testVAL1"}, {"testPARAM2"=>"testVAL2"}]
r = h.inject(:merge)
于 2012-08-08T01:51:51.090 に答える
9

#injectを使用

hashes = [{"testPARAM1"=>"testVAL1"}, {"testPARAM2"=>"testVAL2"}]
merged = hashes.inject({}) { |aggregate, hash| aggregate.merge hash }
merged # => {"testPARAM1"=>"testVAL1", "testPARAM2"=>"testVAL2"}
于 2012-08-08T01:51:09.853 に答える
0

ここでは、 Enumerableクラスからinjectまたはreduceを使用できます。どちらも互いのエイリアスであるため、どちらにもパフォーマンス上の利点はありません。

 sample = [{"testPARAM1"=>"testVAL1"}, {"testPARAM2"=>"testVAL2"}]

 result1 = sample.reduce(:merge)
 # {"testPARAM1"=>"testVAL1", "testPARAM2"=>"testVAL2"}

 result2 = sample.inject(:merge)
 # {"testPARAM1"=>"testVAL1", "testPARAM2"=>"testVAL2"}
于 2019-05-24T16:57:10.827 に答える