添加一对新的哈希,我做:

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

是否有类似的方法从哈希中删除键?

如此:

{:a => 1, :b => 2}.reject! { |k| k == :a }   #=> {:b => 2}

但我希望有这样的东西:

{:a => 1, :b => 2}.delete!(:a)   #=> {:b => 2}

重要的是,返回值将是剩余的散列,所以我可以这样做:

foo(my_hash.reject! { |k| k == my_key })

在一行里。


当前回答

参见Ruby on Rails:删除多个散列键

hash.delete_if{ |k,| keys_to_delete.include? k }

其他回答

Hash#except (Ruby 3.0+)

从Ruby 3.0开始,hash# except是一个内置方法。

因此,不再需要依赖ActiveSupport或编写monkey-patches来使用它。

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

来源:

除了官方Ruby文档。 链接到PR。 Ruby 3.0增加了Hash#except和ENV.except。

有许多方法可以从散列中删除键并在Ruby中获取剩余的散列。

.slice => It will return selected keys and not delete them from the original hash. Use slice! if you want to remove the keys permanently else use simple slice. 2.2.2 :074 > hash = {"one"=>1, "two"=>2, "three"=>3} => {"one"=>1, "two"=>2, "three"=>3} 2.2.2 :075 > hash.slice("one","two") => {"one"=>1, "two"=>2} 2.2.2 :076 > hash => {"one"=>1, "two"=>2, "three"=>3} .delete => It will delete the selected keys from the original hash(it can accept only one key and not more than one). 2.2.2 :094 > hash = {"one"=>1, "two"=>2, "three"=>3} => {"one"=>1, "two"=>2, "three"=>3} 2.2.2 :095 > hash.delete("one") => 1 2.2.2 :096 > hash => {"two"=>2, "three"=>3} .except => It will return the remaining keys but not delete anything from the original hash. Use except! if you want to remove the keys permanently else use simple except. 2.2.2 :097 > hash = {"one"=>1, "two"=>2, "three"=>3} => {"one"=>1, "two"=>2, "three"=>3} 2.2.2 :098 > hash.except("one","two") => {"three"=>3} 2.2.2 :099 > hash => {"one"=>1, "two"=>2, "three"=>3} .delete_if => In case you need to remove a key based on a value. It will obviously remove the matching keys from the original hash. 2.2.2 :115 > hash = {"one"=>1, "two"=>2, "three"=>3, "one_again"=>1} => {"one"=>1, "two"=>2, "three"=>3, "one_again"=>1} 2.2.2 :116 > value = 1 => 1 2.2.2 :117 > hash.delete_if { |k,v| v == value } => {"two"=>2, "three"=>3} 2.2.2 :118 > hash => {"two"=>2, "three"=>3} .compact => It is used to remove all nil values from the hash. Use compact! if you want to remove the nil values permanently else use simple compact. 2.2.2 :119 > hash = {"one"=>1, "two"=>2, "three"=>3, "nothing"=>nil, "no_value"=>nil} => {"one"=>1, "two"=>2, "three"=>3, "nothing"=>nil, "no_value"=>nil} 2.2.2 :120 > hash.compact => {"one"=>1, "two"=>2, "three"=>3}

基于Ruby 2.2.2的结果。

你可以用except!来自facets gem:

>> require 'facets' # or require 'facets/hash/except'
=> true
>> {:a => 1, :b => 2}.except(:a)
=> {:b=>2}

原来的哈希值不会改变。

编辑:正如Russel所说,facets有一些隐藏的问题,并且与ActiveSupport不完全兼容api。另一方面,ActiveSupport不像facet那样完整。最后,我将使用AS,并让边界情况出现在代码中。

在哈希中删除键的多种方法。 你可以使用下面的任何方法

hash = {a: 1, b: 2, c: 3}
hash.except!(:a) # Will remove *a* and return HASH
hash # Output :- {b: 2, c: 3}

hash = {a: 1, b: 2, c: 3}
hash.delete(:a) # will remove *a* and return 1 if *a* not present than return nil

有很多方法,你可以看看Ruby doc of Hash。

谢谢你!

如果你想使用纯Ruby(没有Rails),不想创建扩展方法(也许你只需要在一两个地方使用扩展方法,不想用大量的方法污染命名空间),不想在适当的地方编辑散列(也就是说,你像我一样是函数式编程的粉丝),你可以“选择”:

>> x = {:a => 1, :b => 2, :c => 3}
=> {:a=>1, :b=>2, :c=>3}
>> x.select{|x| x != :a}
=> {:b=>2, :c=>3}
>> x.select{|x| ![:a, :b].include?(x)}
=> {:c=>3}
>> x
=> {:a=>1, :b=>2, :c=>3}