2013-09-27 16 views
7

Ich habe einen Hash, wobei Schlüssel ist eine Zeichenfolge und Wert ist ein Array einer Zeichenfolge. Ich mag etwas wie folgen aus:Hash der Arrays in Ruby

{"k1"=>["v1", "v2"], "k2"=>["v3", "v4"]} 

Ich habe nur einen Hash und ein Array, dies umzusetzen. Ich habe so etwas wie folgt codiert:

hash1 = Hash.new 
arr = Array.new 
arr.push "v1" 
arr.push "v2" 
hash1["k1"] = arr 

#hash is like this: {"k1"=>["v1", "v2"] 
#Now I clear the array to read the new values 

arr. clear 
arr.push "v3" 
arr.push "v4" 
hash1["k2"] = arr 
puts hash1 

#Output: {"k1"=>["v3", "v4"], "k2"=>["v3", "v4"]} 
#Notice that k1's value also got updated 

Dann änderte ich eine Zeile:

hash1 = Hash.new 
arr = Array.new 
arr.push "v1" 
arr.push "v2" 
hash1["k1"] = arr 

arr = [] # ** This is the only changed line. Now k1's value is correct. ** 
arr.push "v3" 
arr.push "v4" 
hash1["k2"] = arr 
puts hash1 
#Output: {"k1"=>["v1", "v2"], "k2"=>["v3", "v4"]} (which I wanted) 

Kann jemand bitte erklären Sie mir, wie ist das passiert? Ich bin sehr neu in Ruby. Im Idealfall, was ist der richtige Weg, um dieses Problem zu programmieren?

+2

"Ich habe nur einen Hash und ein Array, um dies zu implementieren." Nicht in deinem zweiten Beispiel. Dort haben Sie zwei Arrays. – Ajedi32

+2

'{}' ist fast immer vorzuziehen zu 'Hash.new' und' [] 'zu' Array.new'. – tadman

+0

@tadman warum ist es vorzuziehen? Ist es nur für die Lesbarkeit? oder gibt es andere Vorteile? –

Antwort

8

Dies soll Ihnen zeigen, was geschieht (object_id ist dein Freund). (Ich habe einen Unterstrich in die Object_id eingefügt, um Unterschiede leichter zu erkennen.)

hash1 = {}   # => {} 
arr = ["v1", "v2"] # => ["v1", "v2"] 
arr.object_id   # => 7016637_4343580 
hash1["k1"] = arr  # => ["v1", "v2"] 
hash1     # => {"k1"=>["v1", "v2"]} 
hash1["k1"].object_id # => 7016637_4343580 
arr.clear    # => [] 
arr.object_id   # => 7016637_4343580 
arr << "v3" << "v4" # => ["v3", "v4"] 
arr.object_id   # => 7016637_4343580 
hash1["k2"] = arr  # => ["v3", "v4"] 
hash1     # => {"k1"=>["v3", "v4"], "k2"=>["v3", "v4"]} 
hash1["k1"].object_id # => 7016637_4343580 
hash1["k2"].object_id # => 7016637_4166580 

arr = []    # => [] 
arr.object_id   # => 7016637_4036500 
arr = ["v5", "v6"] # => ["v5", "v6"] 
arr.object_id   # => 7016637_3989880 
hash1     # => {"k1"=>["v3", "v4"], "k2"=>["v3", "v4"]} 
hash1["k1"].object_id # => 7016637_4343580 
hash1["k2"] = arr  # => ["v5", "v6"] 
hash1     # => {"k1"=>["v3", "v4"], "k2"=>["v5", "v6"]} 
hash1["k1"].object_id # => 7016637_4343580 
hash1["k2"].object_id # => 7016637_3989880 
+0

nette Erklärung. wenn ich meinen Hash mit Wert v1 oder v2 sortieren möchte, wie soll ich tun? 'hash1.sort_by {| k, v | v.first} '#undefined method '[]' für nil: NilClass ' hash1.sort_by {| k, v | v [0]} '#undefined Methode '[]' für Nil: NilClass – Aparichith

+0

Ich verstehe Ihre Frage nicht ganz. Bitte hinterlassen Sie einen weiteren Kommentar mit einem Beispiel für 'hash1' und wie das Ergebnis des Hashes aussehen soll. –

+0

Betrachten Sie ein Array von Hashes wie diesem '{{" a "=> [576, 236]}, {" z "=> [348, 4859]}, {" b "=> [174, 98] }, {"t" => [165, 145]}, {"u" => [97, 184]}, {"m" => [595, 374]}, {"g" = > [61, 86]}] ' Wie soll ich meine Hash-Reihe unter Verwendung der Summe der Werte für jeden Schlüssel sortieren? wie diese '[{ "z"=> [348, 4859]}, { "a"=> [576, 236]}, { "m"=> [595, 374]}, {"t" => [165, 145]}, {"u" => [97, 184]}, {"b" => [174, 98]}, {"g" => [61 , 86]}] ' – Aparichith

3

Das Array, das Sie auf dem Hash gespeichert wird noch referenziert mit arr so deutlich arr.clear tun und arr.push mit würde aufzuräumen und neue Werte in dem auf dem Hash als auch gespeichert hinzufügen. Jedoch würde arr = [], arr jetzt ein neues Array referenzieren, das sich von dem im Hash gespeicherten unterscheidet.

Und Sie können einfach ein neues Array in den Hash mit:

hash1["k2"] = ["v3", "v4"] 

Oder

hash1["k2"] = %w[v3 v4] 
+2

Hinzufügen zu der Antwort, so dass es funktioniert, tun Sie dies auf Ihrem 'arr',' arr.object_id', erhalten Sie eine Nummer, wenn Sie 'clear' verwenden und erneut die ID überprüfen, es ist das gleiche (immer noch selbe Referenz), wenn Sie arr = [] 'erstellen Sie ein neues Objekt mit dem gleichen Namen, überschreiben Sie das alte, überprüfen Sie es mit' arr.object_id' und Sie haben eine andere ID-Nummer, was bedeutet, eine neue Objekt :) – Gerep