Hinzufügen zu einem vorhandenen Hash in Ruby


102

In Bezug auf das Hinzufügen eines key => valuePaares zu einem vorhandenen aufgefüllten Hash in Ruby arbeite ich gerade an Apress 'Beginning Ruby und habe gerade das Kapitel mit den Hashes abgeschlossen.

Ich versuche, den einfachsten Weg zu finden, um mit Hashes die gleichen Ergebnisse zu erzielen wie mit Arrays:

x = [1, 2, 3, 4]
x << 5
p x

Antworten:


188

Wenn Sie einen Hash haben, können Sie Elemente hinzufügen, indem Sie sie nach Schlüssel referenzieren:

hash = { }
hash[:a] = 'a'
hash[:a]
# => 'a'

Hier wird wie beim Erstellen eines leeren [ ]Arrays { }ein leerer Hash erstellt.

Arrays haben null oder mehr Elemente in einer bestimmten Reihenfolge, wobei Elemente dupliziert werden können. Hashes haben null oder mehr Elemente, die nach Schlüsseln organisiert sind , wobei Schlüssel möglicherweise nicht dupliziert werden, die an diesen Positionen gespeicherten Werte jedoch.

Hashes in Ruby sind sehr flexibel und können Schlüssel von fast jedem Typ haben, den Sie darauf werfen können. Dies unterscheidet es von den Wörterbuchstrukturen, die Sie in anderen Sprachen finden.

Es ist wichtig zu bedenken, dass die Spezifität eines Hash-Schlüssels oft von Bedeutung ist:

hash = { :a => 'a' }

# Fetch with Symbol :a finds the right value
hash[:a]
# => 'a'

# Fetch with the String 'a' finds nothing
hash['a']
# => nil

# Assignment with the key :b adds a new entry
hash[:b] = 'Bee'

# This is then available immediately
hash[:b]
# => "Bee"

# The hash now contains both keys
hash
# => { :a => 'a', :b => 'Bee' }

Ruby on Rails verwirrt dies etwas, indem es HashWithIndifferentAccess bereitstellt, wo es frei zwischen Symbol- und String-Adressierungsmethoden konvertiert.

Sie können auch fast alles indizieren, einschließlich Klassen, Zahlen oder andere Hashes.

hash = { Object => true, Hash => false }

hash[Object]
# => true

hash[Hash]
# => false

hash[Array]
# => nil

Hashes können in Arrays konvertiert werden und umgekehrt:

# Like many things, Hash supports .to_a
{ :a => 'a' }.to_a
# => [[:a, "a"]]

# Hash also has a handy Hash[] method to create new hashes from arrays
Hash[[[:a, "a"]]]
# => {:a=>"a"} 

Wenn es darum geht, Dinge in einen Hash einzufügen, können Sie dies einzeln tun oder die mergeMethode verwenden, um Hashes zu kombinieren:

{ :a => 'a' }.merge(:b => 'b')
# {:a=>'a',:b=>'b'}

Beachten Sie, dass dadurch der ursprüngliche Hash nicht geändert wird, sondern ein neuer zurückgegeben wird. Wenn Sie einen Hash in einen anderen kombinieren möchten, können Sie die folgende merge!Methode verwenden:

hash = { :a => 'a' }

# Returns the result of hash combined with a new hash, but does not alter
# the original hash.
hash.merge(:b => 'b')
# => {:a=>'a',:b=>'b'}

# Nothing has been altered in the original
hash
# => {:a=>'a'}

# Combine the two hashes and store the result in the original
hash.merge!(:b => 'b')
# => {:a=>'a',:b=>'b'}

# Hash has now been altered
hash
# => {:a=>'a',:b=>'b'}

Wie bei vielen Methoden für String und Array gibt das !an, dass es sich um eine In-Place- Operation handelt.


12
Viele wertvolle Informationen, aber es fehlt die grundlegendste Formulierung, die so einfach von @robbrit beantwortet wird.
Danh

1
Bitte bearbeiten Sie Ihre Antwort, um die gestellte Frage tatsächlich zu beantworten, vorzugsweise in der Nähe der Spitze. Es wäre unhöflich von mir, es für dich zu tun.
Stephan

@Stephan Oben wurde ein präziseres Beispiel hinzugefügt.
Tadman


34

Wenn Sie mehr als eine hinzufügen möchten:

hash = {:a => 1, :b => 2}
hash.merge! :c => 3, :d => 4
p hash

8
x = {:ca => "Canada", :us => "United States"}
x[:de] = "Germany"
p x

Ich habe versucht, dies folgendermaßen zu implementieren: x['key'] = "value"Ich erhalte jedoch Fehler. Ich sollte erwähnen, dass ich mit Strings arbeite.
Tom

1
Was ist der Fehler? Es könnte alles sein, es sei denn, Sie sind spezifischer.
Tadman

1
hash = { a: 'a', b: 'b' }
 => {:a=>"a", :b=>"b"}
hash.merge({ c: 'c', d: 'd' })
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 

Gibt den zusammengeführten Wert zurück.

hash
 => {:a=>"a", :b=>"b"} 

Ändert das Aufruferobjekt jedoch nicht

hash = hash.merge({ c: 'c', d: 'd' })
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 
hash
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 

Neuzuweisung macht den Trick.


0
hash {}
hash[:a] = 'a'
hash[:b] = 'b'
hash = {:a => 'a' , :b = > b}

Möglicherweise erhalten Sie Ihren Schlüssel und Wert aus Benutzereingaben, sodass Sie Ruby verwenden können .to_sym kann eine Zeichenfolge in ein Symbol konvertieren , und .to_i konvertiert eine Zeichenfolge in eine Ganzzahl.
Beispielsweise:

movies ={}
movie = gets.chomp
rating = gets.chomp
movies[movie.to_sym] = rating.to_int
# movie will convert to a symbol as a key in our hash, and 
# rating will be an integer as a value.

0

Sie können den seit Ruby 2.0 verfügbaren Double-Splat-Operator verwenden:

h = { a: 1, b: 2 }
h = { **h, c: 3 }
p h
# => {:a=>1, :b=>2, :c=>3}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.