2009-12-12 14 views
13

No tengo idea si esto es un problema Hash o un problema Array, pero no entiendo por qué se requiere el signo asterisco (*) en el tercer ejemplo para obtener un hash lleno de datos. Sin él, produce un hash vacío.¿Por qué necesito asterisco antes de una matriz?

# -*- 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] 
# => {} 

A continuación hay una explicación del método.

--------------------------------------------------------------- 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} 

Respuesta

30

El operador splat (es decir, la *) convierte lo que sería de otra manera una matriz en una lista para la asignación dentro de la hash. Debe dar al operador [] una lista real para convertirla en los pares clave/valor de un hash. (Consulte a continuación un enlace a una breve descripción del operador splat que puede hacer esto (desenrollar una matriz en una lista) o al revés (recopilar una lista en una matriz).)

La forma en que lo hizo anteriormente , le da Hash[]un número impar de elementos, es decir, una única matriz. (Piense en lo que produce [[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten. Otorga [:first_name, 'Shane', :last_name, 'Havie'].) Como dicen los documentos que citó, el operador [] debe tener un número par de elementos. Tenga en cuenta que el siguiente (aunque inútil) hace trabajo:

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

(No está claro para mí por qué no obtiene el "número impar de argumentos para Hash" error al utilizar el código que tiene arriba - como lo haces si pruebas Hash[1].)

Un ejemplo más simple puede hacerlo más claro. Primero, pasando un elemento, una matriz. La apertura de la matriz con *Hash[] a mano una lista de elementos:

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

Ver this blog post para una explicación más completa. También puede encontrar útil this short write-up about the splat operator.

+0

Muchas gracias por su explicación detallada y enlaces. Ahora entiendo completamente qué es esto. Ahora todo tiene sentido. –

Cuestiones relacionadas