web-dev-qa-db-ja.com

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

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

a = []
a << "foo"

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

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

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

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

しかし、それは私が望んでいません。

ありがとう。

70
jcarpio

merge! があります。

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

ハッシュは本質的に順序付けられていないため、追加するという概念はありません。ただし、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
73
Mark Thomas

いいえ、キー/値のペアを追加できるとは思いません。私が知っている唯一のことcloseststoreメソッドを使用している:

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

おそらく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"} 
3
Michael Durrant

同様に、merge!storeは、キー名に応じてexistingハッシュを異なる方法で処理するため、好みに影響します。それ以外の構文の観点からは、merge!key: "value"構文は、JavaScriptおよびPythonと密接に一致します。個人的には、コンマ区切りのキーと値のペアが嫌いです。

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"}

シャベル演算子<<を機能させるには、 Mark Thomas の答えを使用することをお勧めします。

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
1
Caner Çakmak