Rubyで<<を使用してハッシュにキーと値のペアを追加します


80

Rubyでは、<<:を使用して既存の配列に値を追加できます。

a = []
a << "foo"

しかし、既存のハッシュにキーと値のペアを追加することもできますか?

h = {}
h << :key "bar"

私はあなたができることを知っています:

h[:key] = ""
h[:key] << "bar"

しかし、それは私が望んでいないことです。

ありがとう。


20
なぜh[:key] = "bar"ですか?
ハウレス2013年

4
これは機能しません:h[:key] << "bar"
Chris Nielsen

回答:


141

ありますmerge!

h = {}
h.merge!(key: "bar")
# => {:key=>"bar"}

3
merge!実際に別の目的で使用されるため、単に新しいキーと値のペアを作成することには適さないと思います。
PericlesTheo 2013年

いい視点ね。OPが投稿しなかった他の要因によっても終わるかもしれないと思います。
Michael Durrant 2013年

1
ああ、ありがとう。storeメソッドは似たようなことをしているようです。<<配列に追加する方法として言及されていたが、ハッシュに対して機能するかどうかを確認したかったので、これは主に学術的な質問でした。再度、感謝します。
jcarpio 2013年

5
違いは次のとおりstoreです。新しいペアを追加するだけで、キーがすでに存在するかどうかは関係ありません。merge!方法は少しばかりのペアを追加するよりもありませんので、しかし、重複したキーを持つエントリが上書きされます。2つをベンチマークstoreすると、より高速であることがわかります(ただし、特に小さなハッシュでは些細なことです)
PericlesTheo

2
@jcarpioありがとう。レシーバー配列を返すのとHash#merge!同じように、レシーバーハッシュをArray#<<返します。Hash#storeまったく違うものです。また、key: "bar"引数の位置にハッシュ構文の糖衣構文があるので、これが表記法に最も近いと思いました。私はこれがあなたが望んでいたものに近いことを知っていました。
さわ2013年

89

ハッシュは本質的に順序付けられていないため、追加の概念はありません。ただし、1.9以降のRubyハッシュは挿入順序を維持します。新しいキーと値のペアを追加する方法は次のとおりです。

最も簡単な解決策は

h[:key] = "bar"

メソッドが必要な場合は、次を使用しますstore

h.store(:key, "bar")

本当に「シャベル」演算子(<<)を使用したい場合は、実際にはハッシュの値に配列として追加されているため、キーを指定する必要があります。

h[:key] << "bar"

上記は、キーが存在する場合にのみ機能します。新しいキーを追加するには、ハッシュをデフォルト値で初期化する必要があります。これは次のように実行できます。

h = Hash.new {|h, k| h[k] = ''}
h[:key] << "bar"

作成した方法で機能するシャベル演算子を含めるために、Hashにモンキーパッチを適用したくなるかもしれません。

class Hash
  def <<(k,v)
    self.store(k,v)
  end
end

ただし、これは、他のコンテキストでショベル演算子に適用される「構文糖衣構文」を継承しません。

h << :key, "bar" #doesn't work
h.<< :key, "bar" #works

徹底!貢献と洞察に感謝します。
jcarpio 2013年

注意すべき点として、Ruby 1.9以降、ハッシュが注文されています。

1
Ruby 1.9+は挿入順序を維持しますが、データ構造としてのハッシュには、いかなる種類の固有の順序の概念もありません。
マークトーマス

27

いいえ、キーと値のペアを追加することはできないと思います。私が知っている最も近い唯一のことは、次のstore方法を使用することです。

h = {}
h.store("key", "value")

3

おそらくあなたはHash#mergeが欲しいですか?

1.9.3p194 :015 > h={}
 => {} 
1.9.3p194 :016 > h.merge(:key => 'bar')
 => {:key=>"bar"} 
1.9.3p194 :017 > 

アレイをその場で変更したい場合は、 merge!

1.9.3p194 :016 > h.merge!(:key => 'bar')
 => {:key=>"bar"} 

merge新しい配列を返すので、それは良い考えではないと思います。新しいペアを既存のハッシュに追加しません。
PericlesTheo 2013年

どの程度merge!(つまり、既存のアレイに)の代わりにmerge
Michael Durrant 2013年

1
merge!技術的にはこのコンテキストで機能しますが、単に新しいペアを追加するのではなく、2つのハッシュをマージするために使用する必要があると思います。また、ベンチマークを行うとmerge!store;)よりも遅くなります
PericlesTheo

3

それらがそうであるように、merge!そしてキー名に応じて既存のハッシュを異なってstore扱うので、あなたの好みに影響を与えます。構文の観点から、それ以外は、の構文は密接JavaScriptとPythonのに対して、最大一致します。個人的には、キーと値のペアをコンマで区切るのはいつも嫌いでした。merge!key: "value"

hash = {}
hash.merge!(key: "value")
hash.merge!(:key => "value")
puts hash

{:key=>"value"}

hash = {}
hash.store(:key, "value")
hash.store("key", "value")
puts hash

{:key=>"value", "key"=>"value"}

ショベルオペレータ取得するには<<、作業を、私は使用して助言するマーク・トーマスの答えを。


1

同様のことをしなければなりませんでしたが、同じキーで値を追加する必要がありました。マージまたは更新を使用すると、同じキーで値をプッシュできません。そのため、ハッシュの配列を使用する必要がありました。

    my_hash_static = {:header =>{:company => 'xx', :usercode => 'xx', :password => 'xx',
                      :type=> 'n:n', :msgheader => from}, :body=>[]}
    my_hash_dynamic = {:mp=>{:msg=>message, :no=>phones} }        
    my_hash_full = my_hash_static[:body].push my_hash_dynamic
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.