In Ruby können Werte mit <<: an vorhandene Arrays angehängt werden:
a = []
a << "foo"
Können Sie aber 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.
h[:key] = "bar"
?h[:key] << "bar"
Antworten:
Es gibt
merge!
.h = {} h.merge!(key: "bar") # => {:key=>"bar"}
quelle
merge!
einfach ein neues Schlüssel / Wert-Paar erstellen kann, da es tatsächlich für einen anderen Zweck verwendet wird.store
Fügt einfach ein neues Paar hinzu, es ist egal, ob der Schlüssel bereits vorhanden ist. mitmerge!
jedoch Einträge mit Nachschlüssel außer Kraft gesetzt werden , so dass die Methode ein bisschen mehr als nur Paare hinzuzufügen. Wenn Sie die beiden vergleichen, werden Sie feststellenstore
, dass Sie schneller sind (trivial, jedoch besonders bei kleinen Hashes)Hash#merge!
Gibt den Empfänger-Hash genauso zurück wieArray#<<
das Empfänger-Array.Hash#store
ist eine ganz andere Sache. Mit der Hash-Syntax Zuckerkey: "bar"
in der Argumentationsposition dachte ich auch, dass dies der Punkt ist, den Sie Ihrer Notation am nächsten kommen können. Ich wusste, dass dieser näher an dem ist, was Sie wollten.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 finden Sie Möglichkeiten zum Hinzufügen neuer Schlüssel / Wert-Paare.
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 , wird dieser tatsächlich an den Wert des Hash als Array angehängt, und Sie müssen den Schlüssel angeben:h[:key] << "bar"
Das Obige funktioniert nur, wenn der Schlüssel vorhanden ist. Um einen neuen Schlüssel anzuhängen, 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, Hash-Affen zu patchen, um einen Schaufeloperator einzuschließen, der so funktioniert, wie Sie es geschrieben haben:
class Hash def <<(k,v) self.store(k,v) end end
Dies erbt jedoch nicht den "syntaktischen Zucker", der in anderen Kontexten auf den Schaufeloperator angewendet wird:
h << :key, "bar" #doesn't work h.<< :key, "bar" #works
quelle
Nein, ich glaube nicht, dass Sie Schlüssel / Wert-Paare anhängen können. Das einzige, was mir am nächsten kommt , ist die Verwendung der
store
Methode:h = {} h.store("key", "value")
quelle
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 an Ort und Stelle ändern möchten, verwenden Sie
merge!
1.9.3p194 :016 > h.merge!(:key => 'bar') => {:key=>"bar"}
quelle
merge
es eine gute Idee ist, weil es ein neues Array zurückgibt; Das neue Paar wird nicht zum vorhandenen Hash hinzugefügt.merge!
(dh zu vorhandenen Array) stattmerge
?merge!
Technisch funktioniert dies in diesem Zusammenhang, aber ich denke, es sollte zum Zusammenführen von zwei Hashes verwendet werden, anstatt einfach ein neues Paar hinzuzufügen. Auch wenn Sie Benchmarking istmerge!
, ist es langsamer alsstore
;)Ähnlich wie sie sind,
merge!
undstore
behandeln bestehende Hashes unterschiedlich auf Keynames abhängig und wird daher Ihre Präferenz beeinflussen. Anders als das aus einer Syntax Sichtmerge!
‚skey: "value"
Syntax entspricht eng gegen JavaScript und Python. 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
hash = {} hash.store(:key, "value") hash.store("key", "value") puts hash
Um den Schaufelbediener zum Laufen zu bringen
<<
, würde ich empfehlen, die Antwort von Mark Thomas zu verwenden .quelle
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 Tasten ü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
quelle