2011-04-19 9 views
5

En Ruby (o rieles), podemos hacerEn Ruby or Rails, hash.merge ({: order => 'asc'}) puede devolver un nuevo hash con una nueva clave. ¿Qué puede devolver un nuevo hash con una clave eliminada?

new_params = params.merge({:order => 'asc'}) 

y ahora new_params es un hash con una clave añadido :order.

¿Pero hay una línea que puede devolver el hash con una tecla eliminada? La línea

new_params = params.delete(:order) 

no funcionará porque el método delete devuelve el valor y eso es todo. ¿Tenemos que hacerlo en 3 pasos?

tmp_params = params 
tmp_params.delete(:order) 
return tmp_params 

¿Hay una manera mejor? Porque quiero hacer un

new_params = (params[:order].blank? || params[:order] == 'desc') ? 
       params.merge({:order => 'asc') : 
       (foo = params; foo.delete(:order); foo) # return foo 

pero la última línea anterior es algo torpe. Hay una mejor manera de hacerlo?

(nota: debido a que el orden predeterminado es 'desc', así que cuando no hay order parámetro, que significa que es el defecto y es desc, a continuación, activar la función de añadir order=asc, pero por lo demás, basta con retirar el parámetro order por lo que es de nuevo a la orden predeterminado de desc)

+0

¿Quieres cambiar (destrucción) 'params'? Si lo hace, debe hacerlo directamente como 'tmp_params.delete (: order)'. De lo contrario, debe 'dup' antes de' delete'. – sawa

Respuesta

10

ActiveSupport añade un método Hash#except:

h1 = { a: 1, b: 2, c: 3 } 
h1.except(:a) #=> {:b=>2, :c=>3} 

un ejemplo más complicado:

h1 = { a:1, b: 2, c: 3 } 
h2 = { b: 3, d: 5 } 
h1.merge(h2).except(*h1.keys-h2.keys) #=> {:b=>3, :d=>5} 

Esto actualizará las claves que están presentes en h1 con los de h2, añadir los nuevos de h2 y quitar los que están en h1 pero no en h2.

1

uso rechazar:

{:hello=> 'aaa'}.reject {| key, value | key == :hello} #=> {} 
1

Si no quiere depender de ActiveSupport puede utilizar:

 
params.delete_if {|key, value| key == :order } 
+0

para resumir, el método 'except' y' reject' no cambia el hash original, mientras que 'delete_if' en realidad cambia el hash original –

Cuestiones relacionadas