2013-09-27 10 views
7

Ho un hash, dove key è una stringa e value è un array di una stringa. voglio qualcosa di simile:Hash of Arrays in Ruby

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

ho solo un hash e un array per implementare questo. Ho codificato qualcosa di simile:

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 

poi ho cambiato una sola riga:

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) 

Per favore qualcuno può spiegare come avviene questo? Sono molto nuovo a Ruby. Idealmente, qual è il modo corretto per codificare questo problema?

+2

"Ho solo un hash e un array per implementarlo." Non nel tuo secondo esempio. Lì hai due array. – Ajedi32

+2

'{}' è quasi sempre preferibile a 'Hash.new', e' [] 'a' Array.new'. – tadman

+0

@tadman perché è preferibile? È solo per la leggibilità? o ci sono altri benefici? –

risposta

8

Questo dovrebbe mostrare ciò che sta accadendo (object_id è tuo amico). (Ho inserito un carattere di sottolineatura in Object_id per semplificare la visualizzazione delle differenze.)

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

bella spiegazione. se voglio ordinare il mio hash con valore v1 o v2 come devo fare? 'hash1.sort_by {| k, v | v.first} 'metodo #undefined '[]' per nil: NilClass ' hash1.sort_by {| k, v | v [0]} 'metodo #undefined '[]' per nil: NilClass – Aparichith

+0

Non capisco la tua domanda. Per favore lascia un altro commento con un esempio di 'hash1' e cosa vorresti che fosse il risultato dell'hash. –

+0

considera un array di hash come questo '[{" a "=> [576, 236]}, {" z "=> [348, 4859]}, {" b "=> [174, 98] }, {"t" => [165, 145]}, {"u" => [97, 184]}, {"m" => [595, 374]}, {"g" = > [61, 86]}] ' come devo ordinare il mio array di hash usando la somma dei valori per ogni chiave? come questo '[{ "z"=> [348, 4859]}, { "a"=> [576, 236]}, { "m"=> [595, 374]}, {"t" => [165, 145]}, {"u" => [97, 184]}, {"b" => [174, 98]}, {"g" => [61 , 86]}] ' – Aparichith

3

L'array è stato salvato sul hash è ancora fatto riferimento con arr facendo in modo così chiaro e arr.clear utilizzando arr.push sarebbe ripulire e aggiungere nuovi valori a quella salvata sul hash pure. Tuttavia, facendo arr = [], arr farebbe ora riferimento a un nuovo array diverso da quello salvato in hash.

E si può semplicemente aggiungere un nuovo array di hash con:

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

O

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

Aggiungendo alla risposta in modo che tu possa vederlo funzionare, fallo sul tuo 'arr', 'arr.object_id', riceverai un numero, quando usi' clear' e ricontrolla l'id, è lo stesso (ancora stesso riferimento), quando you 'arr = [] 'crei un nuovo oggetto con lo stesso nome, sovrascrivendo quello vecchio, controllalo con' arr.object_id' e avrai un numero identificativo diverso, il che significa, un nuovo oggetto :) – Gerep