web-dev-qa-db-de.com

Hänge das Schlüssel / Wert-Paar mit << in Ruby an den Hash an

In Ruby können mit << Werte an vorhandene Arrays angehängt werden:

a = []
a << "foo"

aber können Sie auch Schlüssel/Wert-Paare an einen vorhandenen Hash anhängen?

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

Ich weiß, dass Sie Folgendes tun können:

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

aber das will ich nicht.

Vielen Dank.

71
jcarpio

Es gibt merge! .

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

Da Hashes nicht von Natur aus geordnet sind, gibt es keine Vorstellung von Anhängen. Ruby Hashes seit 1.9 behalten jedoch die Einfügereihenfolge bei. Hier sind die Möglichkeiten, neue Schlüssel/Wert-Paare hinzuzufügen.

Die einfachste Lösung ist

h[:key] = "bar"

Wenn Sie eine Methode wünschen, verwenden Sie store:

h.store(:key, "bar")

Wenn Sie wirklich, wirklich einen "Schaufel" -Operator verwenden möchten (<<), es wird tatsächlich als Array an den Wert des Hash angehängt, und Sie müssen den Schlüssel angeben:

h[:key] << "bar"

Das Obige funktioniert nur, wenn der Schlüssel existiert. Um einen neuen Schlüssel anzufügen, müssen Sie den Hash mit einem Standardwert initialisieren. Dies können Sie folgendermaßen tun:

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

Sie könnten versucht sein, das Affen-Patch-Hash zu verwenden, um einen Schaufeloperator hinzuzufügen, der wie folgt funktioniert:

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

Dies erbt jedoch nicht den "syntaktischen Zucker", der in anderen Zusammenhängen auf den Schaufeloperator angewendet wird:

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

Nein, ich glaube nicht, dass Sie Schlüssel/Wert-Paare anhängen können. Die einzige Sache , die mir am nächsten kommt , ist die Verwendung der store -Methode:

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

Vielleicht möchten Sie Hash # zusammenführen?

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

Wenn Sie das Array ändern möchten, verwenden Sie merge!

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

Ähnlich wie sie sind, behandeln merge! Und store vorhandene Hashes in Abhängigkeit von den Schlüsselnamen unterschiedlich und wirken sich daher auf Ihre Präferenz aus . Vom Standpunkt der Syntax aus gesehen stimmt die Syntax von merge!key: "value" Sehr gut mit der von JavaScript und Python überein. Ich persönlich habe es immer gehasst, Schlüssel-Wert-Paare durch Kommas zu trennen.

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

Um den Schaufeloperator << Zum Laufen zu bringen, würde ich empfehlen, die Antwort von Mark Thomas zu verwenden.

1

Ich musste etwas Ähnliches tun, aber ich musste Werte mit denselben Schlüsseln hinzufügen. Wenn ich Merge oder Update verwende, kann ich keine Werte mit denselben Schlüsseln übertragen. Also musste ich eine Reihe von Hashes verwenden.

    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