在Ruby或Rails中,hash.merge({:order =>'asc'})可以返回带有新键的新哈希。什么可以返回带有已删除密钥的新哈希?

时间:2011-04-19 12:07:04

标签: ruby-on-rails ruby

在Ruby(或Rails)中,我们可以做到

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

现在new_params是一个添加了密钥:order的哈希。

但是有一行可以返回带有删除键的哈希吗?这条线

new_params = params.delete(:order)

将无效,因为delete方法返回值,就是这样。我们必须分三步完成吗?

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

有更好的方法吗?因为我想做一个

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

但上面的最后一行有点笨拙。有没有更好的方法呢?

(注意:因为默认顺序为'desc',所以当没有order参数时,这意味着它是默认值desc,然后将其切换为添加order=asc },但除此之外,只需删除参数order,使其恢复为默认顺序desc

3 个答案:

答案 0 :(得分:10)

ActiveSupport添加了Hash#except方法:

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

一个更复杂的例子:

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

这将使用h1中的密钥更新h2中的密钥,添加h2中的新密钥并删除h1中的密钥在h2

答案 1 :(得分:1)

使用拒绝:

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

答案 2 :(得分:1)

如果您不想依赖ActiveSupport,可以使用:

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