2009-05-08 23 views
9

¿Hay una mejor manera de hacer esto? (Se ve torpe)¿Mejor forma de llenar un hash Ruby?

form_params = {} 
form_params['tid'] = tid 
form_params['qid'] = qid 
form_params['pri'] = pri 
form_params['sec'] = sec 
form_params['to_u'] = to_u 
form_params['to_d'] = to_d 
form_params['from'] = from 
form_params['wl'] = wl 
+0

El sabor preciso de clunkiness se llama SECO, https://en.wikipedia.org/wiki/Don't_repeat_yourself. –

Respuesta

8

Ligera modificación de lo anterior, ya que su ejemplo tenía las llaves de cadena:

form_params = {} 
%w(tid qid pri sec to_u to_d from wl).each{|v| form_params[v] = send(v)} 
20
form_params = { "tid" => tid, "qid" => qid }  

O usted podría hacer

form_params = Hash["tid", tid, "qid", qid]  #=> {"tid"=>tid, "qid"=>qid} 
form_params = Hash["tid" => tid, "qid" => qid] #=> {"tid"=>tid, "qid"=>qid} 
form_params = Hash[tid => tid, qid => qid]  #=> {"tid"=>tid, "qid"=>qid} 

(NB. El último es nuevo para el 1,9 y hace que su clave symbols en lugar de strings)

{tid: tid, qid: qid}

Las claves y los valores se presentan en pares, por lo que debe haber un número par mber de argumentos.

+2

A partir de Ruby 1.9, si está de acuerdo con que las claves sean símbolos en lugar de cadenas, también puede decir {tid: tid, qid: qid}. – Chuck

+0

: does not work, => does – Schildmeijer

+0

No, el colon funciona como dije. Acabo de probar. ruby -e "tid = 12; puts ({tid: tid})" prints "{: tid => 12}". El formulario => no funciona; imprime {12 => 12}. – Chuck

7

Si el rendimiento no es importante éste podría verse mejor:

form_params = {} 
['tid', 'qid', 'pri', 'sec', 'to_u', 'to_d', 'from', 'wl'].each do |v| 
    form_params[v] = eval(v) 
end 

Si esos nombres son en realidad métodos que puede sustituir a eval por el rápido send:

form_params[v] = send(v.to_sym) 

(Actualización) Un Manera alternativa (y más elegante) usando inject:

form_params = ['tid', 'qid', 'pri', 'sec', 'to_u', 'to_d', 'from', 'wl'].inject({}) { |h, v| h[v] = send(v); h } 
0

he creado una clase personalizada denominada MoreOpenStruct para hacer frente a la falta de Hash de la estética, y el uso de esa clase, su ejemplo se vería así:

form_params = MoreOpenStruct.new 
form_params.tid = tid 
form_params.qid = qid 
form_params.pri = pri 
form_params.sec = sec 
form_params.to_u = to_u 
form_params.to_d = to_d 
form_params.from = from 
form_params.wl = wl 

form_params_hash = form_params._to_hash 
    #=> { :tid => tid, :qid => qid, etc } 

Si necesita literales de cadena en lugar de símbolos como la clave para su hash, entonces se requieren un par de ajustes más.

Uso mi clase de estructura personalizada cuando quiero fácil de leer/manipular Hashes, pero si todo lo que hace es una tarea y no es necesario analizar el hash más allá de eso, usaría la solución de Roger.

0

Las otras opciones sería la creación de una clase basada Struct para almacenar estos valores en, por ejemplo:.

FormParams = Struct.new(:tid, :qid, :pri, :sec, :to_u, :to_d, :from, :wl) 

Entonces serías capaz de inicializar la instancia form_params en una variedad de maneras:

form_params = FormParams.new(:tid => tid, :qid => qid, # etc ... 
form_params = FormParams.new(tid, qid, pri, sec, to_u, to_d, from, wl) 
form_params = FormParams.new 
form_params.tid = tid 
form_params.gid = gid 
# etc ... 
1

Y, sin embargo otra forma, para Ruby 1.9:

form_params = {tid: "tid", qid: "qid", ...} 
1
Hash[%w(tid qid pri sec to_u to_d from wl).collect{|x| [x,send(x)]}] 
0
a = %w(tid quid pri sec to_u to_d from wl) 
form_params = Hash[a.zip(a.collect {|v| send(v) })]