/ / Come posso inizializzare una matrice all'interno di un hash in Ruby: ruby, array, hash

Come posso inizializzare una matrice all'interno di un hash in Ruby: ruby, array, hash

Sto cercando di inizializzare un hash di array come

@my_hash = Hash.new(Array.new)

così che io possa:

@my_hash["hello"].push("in the street")
=> ["in the street"]
@my_hash["hello"].push("at home")
=> ["in the street", "at home"]
@my_hash["hello"]
=>["in the street", "at home"]

Il problema è che viene restituita anche una nuova chiave di hash ["in the street", "at home"]

@my_hash["bye"]
=> ["in the street", "at home"]
@my_hash["xxx"]
=> ["in the street", "at home"]

!!! ???

Cosa sto facendo male quale sarebbe il modo corretto per inizializzare un hash di array?

risposte:

85 per risposta № 1
@my_hash = Hash.new(Array.new)

Questo crea esattamente un oggetto array, che viene restituito ogni volta che non viene trovata una chiave. Dal momento che modificherai sempre quell'array e non ne creerai mai uno nuovo, tutte le tue chiavi verranno mappate allo stesso array.

Quello che vuoi fare è:

@my_hash = Hash.new {|h,k| h[k] = Array.new }

o semplicemente

@my_hash = Hash.new {|h,k| h[k] = [] }

Passando un blocco a Hash.new differisce dal semplice passaggio di un argomento in 2 modi:

  1. Il blocco viene eseguito ogni volta che non viene trovata una chiave. Quindi otterrai ogni volta un nuovo array. Nella versione con un argomento, quell'argomento viene valutato una volta (in precedenza) new viene chiamato) e il risultato di ciò viene restituito ogni volta.

  2. Facendo h[k] = in realtà inserisci la chiave nell'hash. Se non lo fai, accedi @my_hash[some_key] in realtà non causa some_key da inserire nell'hash.


7 per risposta № 2

Prova questo:

@my_hash = Hash.new { |h, k| h[k] = Array.new }

2 per risposta № 3

L'argomento per Hash.new è per il valore predefinito per le nuove chiavi di hash, quindi quando si passa a un riferimento tale riferimento verrà utilizzato per nuove chiavi di hash. Stai aggiornando quel riferimento quando chiami ...

hash["key"].push "value"

Devi passare un nuovo riferimento nella chiave hash prima di spingere i valori ad esso ...

hash["key1"] = Array.new
hash["key1"].push "value1"
hash["key2"] = Array.new
hash["key2"].push "value2

Potresti provare a racchiuderlo in un metodo di supporto.