2009-12-12 11 views
13

Non ho idea se si tratti di un problema di hash o di array, ma non riesco a capire perché il segno asterisco (*) sia richiesto nel terzo esempio per ottenere un hash pieno di dati. Senza di esso, emette un hash vuoto.Perché ho bisogno dell'asterisco prima di un array?

# -*- coding: utf-8 -*- 
require 'pp' 
pp [[:first_name, 'Shane'], [:last_name, 'Harvie']] 
# => [[:first_name, "Shane"], [:last_name, "Harvie"]] 

pp [[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten 
# => [:first_name, "Shane", :last_name, "Harvie"] 

pp Hash[*[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten] 
# => {:first_name=>"Shane", :last_name=>"Harvie"} 

pp Hash[[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten] 
# => {} 

Di seguito è riportata una spiegazione del metodo.

--------------------------------------------------------------- Hash::[] 
    Hash[ [key =>|, value]* ] => hash 

    From Ruby 1.8 
------------------------------------------------------------------------ 
    Creates a new hash populated with the given objects. Equivalent to 
    the literal +{ _key_, _value_, ... }+. Keys and values occur in 
    pairs, so there must be an even number of arguments. 

     Hash["a", 100, "b", 200]  #=> {"a"=>100, "b"=>200} 
     Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200} 
     { "a" => 100, "b" => 200 }  #=> {"a"=>100, "b"=>200} 

risposta

30

L'operatore splat (cioè, il *) diventa quello che altrimenti sarebbe un array in un elenco per l'assegnazione all'interno hash. Devi dare all'operatore [] un vero e proprio elenco da trasformare nelle coppie chiave/valore di un hash. (Vedi sotto per un link ad una breve descrizione dell'operatore splat che in realtà può fare questo (svolgere un array in un elenco) o il contrario (raccogliere un elenco in un array).)

Il modo in cui lo hai fatto sopra , dai un numero dispari di articoli, ovvero un singolo array. (Pensa a cosa produce [[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten. Produce [:first_name, 'Shane', :last_name, 'Havie'].) Come i documenti che hai citato dicono, l'operatore [] deve avere un numero pari di elementi. Si noti che il seguente (anche se inutile) fa lavoro:

>> Hash[[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten, 1] 
=> {[:first_name, "Shane", :last_name, "Harvie"]=>1} 

(Non è chiaro per me il motivo per cui non si ottiene il "numero dispari di argomenti per Hash" l'errore quando si utilizza il codice che avete sopra - come lo fai se provi Hash[1].)

Un esempio più semplice può renderlo più chiaro. Primo, passando in un oggetto, un array. L'apertura della matrice con * a portata di mano Hash[] un elenco di elementi:

>> Hash[['foo', 'bar', 'bizz', 'buzz']] 
=> {} 
>> Hash[*['foo', 'bar', 'bizz', 'buzz']] 
=> {"foo"=>"bar", "bizz"=>"buzz"} 

Vedi this blog post per una spiegazione più completa. Potresti anche trovare utile this short write-up about the splat operator.

+0

Grazie mille per la spiegazione dettagliata e collegamenti. Ora capisco perfettamente di cosa si tratta. Ora tutto ha un senso. –

Problemi correlati