如何在 Ruby/Rails 中从哈希中删除密钥并获取剩余的哈希?
要向 Hash 添加新对,我这样做:
{:a => 1, :b => 2}.merge!({:c => 3}) #=> {:a => 1, :b => 2, :c => 3}
是否有类似的方法从 Hash 中删除密钥?
这是可行的:
{: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 })
在一行中。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
对于那些刚刚来到这里了解如何从哈希中删除键/值对的人,您可以使用:
hash.delete(key)
对于其他来这里阅读完全不同内容的文字墙的人,您可以阅读此答案的其余部分:
Rails 有一个 except/ except!方法 返回删除了这些键的哈希值。如果您已经在使用 Rails,那么创建您自己的版本是没有意义的。
For those of you who just came here to know how to delete a key/value pair from a hash, you can use:
hash.delete(key)
For the rest of you who came here to read a wall of text about something entirely different, you can read the rest of this answer:
Rails has an except/except! method that returns the hash with those keys removed. If you're already using Rails, there's no sense in creating your own version of this.
为什么不直接使用:
hash
现在是您要查找的“剩余哈希”。Why not just use:
hash
is now the "remaining hash" you're looking for.Oneliner 纯红宝石,仅适用于红宝石 > 1.9.x:
Tap 方法总是返回被调用的对象...
否则,如果您需要
active_support/core_ext/hash
(每个 Rails 应用程序都自动需要),您可以使用根据您的需要使用以下方法之一:except 使用黑名单方法,因此它会删除所有列为参数的键,而 slice 使用白名单方法,因此它会删除所有未列为参数的键。还存在这些方法的 bang 版本(
except!
和slice!
),它们修改给定的哈希值,但它们的返回值不同,它们都返回一个哈希值。它表示为slice!
删除的键以及为except!
保留的键:Oneliner plain ruby, it works only with ruby > 1.9.x:
Tap method always return the object on which is invoked...
Otherwise if you have required
active_support/core_ext/hash
(which is automatically required in every Rails application) you can use one of the following methods depending on your needs:except uses a blacklist approach, so it removes all the keys listed as args, while slice uses a whitelist approach, so it removes all keys that aren't listed as arguments. There also exist the bang version of those method (
except!
andslice!
) which modify the given hash but their return value is different both of them return an hash. It represents the removed keys forslice!
and the keys that are kept for theexcept!
:在 Ruby 中,有很多方法可以从哈希中删除键并获取剩余的哈希。
.slice
=>;它将返回选定的键,而不是将它们从原始哈希中删除。如果您想永久删除密钥,请使用slice!
,否则请使用简单的slice
。<前><代码>2.2.2 :074>哈希 = {“一”=>1,“二”=>2,“三”=>3}
=> {“一”=>1,“二”=>2,“三”=>3}
2.2.2:075> hash.slice("一","二")
=> {“一”=>1,“二”=>2}
2.2.2:076>散列
=> {“一”=>1,“二”=>2,“三”=>3}
.删除
=>它将从原始哈希中删除选定的键(它只能接受一个键,不能接受多个键)。<前><代码>2.2.2 :094>哈希 = {“一”=>1,“二”=>2,“三”=>3}
=> {“一”=>1,“二”=>2,“三”=>3}
2.2.2:095> hash.delete("一")
=> 1
2.2.2:096>散列
=> {“二”=>2,“三”=>3}
. except
=>;它将返回剩余的键,但不会从原始哈希中删除任何内容。如果您想永久删除密钥,请使用except!
,否则请使用简单的except
。<前><代码>2.2.2 :097>哈希 = {“一”=>1,“二”=>2,“三”=>3}
=> {“一”=>1,“二”=>2,“三”=>3}
2.2.2:098> hash. except("一","二")
=> {“三”=>3}
2.2.2:099>散列
=> {“一”=>1,“二”=>2,“三”=>3}
.delete_if
=>;如果您需要根据值删除键。显然,它会从原始哈希中删除匹配的键。<前><代码>2.2.2 :115>哈希= {“一”=> 1,“二”=> 2,“三”=> 3,“one_again”=> 1}
=> {“一”=>1、“二”=>2、“三”=>3、“one_again”=>1}
2.2.2:116>值 = 1
=> 1
2.2.2:117> hash.delete_if { |k,v| v == 值 }
=> {“二”=>2,“三”=>3}
2.2.2:118>散列
=> {“二”=>2,“三”=>3}
.compact
=>;它用于从哈希中删除所有nil
值。如果您想永久删除nil
值,请使用compact!
,否则请使用简单的compact
。<前><代码>2.2.2 :119> hash = {“一”=>1,“二”=>2,“三”=>3,“无”=>nil,“no_value”=>nil}
=> {“一”=>1,“二”=>2,“三”=>3,“无”=>nil,“no_value”=>nil}
2.2.2:120>哈希紧凑型
=> {“一”=>1,“二”=>2,“三”=>3}
结果基于 Ruby 2.2.2。
There are many ways to remove a key from a hash and get the remaining hash in Ruby.
.slice
=> It will return selected keys and not delete them from the original hash. Useslice!
if you want to remove the keys permanently else use simpleslice
..delete
=> It will delete the selected keys from the original hash(it can accept only one key and not more than one)..except
=> It will return the remaining keys but not delete anything from the original hash. Useexcept!
if you want to remove the keys permanently else use simpleexcept
..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..compact
=> It is used to remove allnil
values from the hash. Usecompact!
if you want to remove thenil
values permanently else use simplecompact
.Results based on Ruby 2.2.2.
如果你想使用纯 Ruby(没有 Rails),不想创建扩展方法(也许你只在一两个地方需要这个,并且不想用大量方法污染命名空间)并且不想就地编辑哈希(即,您像我一样喜欢函数式编程),您可以“选择”:
If you want to use pure Ruby (no Rails), don't want to create extension methods (maybe you need this only in one or two places and don't want to pollute namespace with tons of methods) and don't want to edit hash in place (i.e., you're fan of functional programming like me), you can 'select':
Hash#except (Ruby 3.0+)
从 Ruby 3.0 开始,Hash# except 是一个内置方法。
因此,不再需要依赖 ActiveSupport 或编写猴子补丁来使用它。
来源:
Hash#except (Ruby 3.0+)
Starting from Ruby 3.0, Hash#except is a build-in method.
As a result, there is no more need to depend on ActiveSupport or write monkey-patches in order to use it.
Sources:
我已经设置了这个,以便 .remove 返回已删除键的哈希副本,而删除!修改哈希本身。这符合红宝石约定。例如,从控制台
I've set this up so that .remove returns a copy of the hash with the keys removed, while remove! modifies the hash itself. This is in keeping with ruby conventions. eg, from the console
您可以使用
facets
gem 中的except!
:原始哈希值不会改变。
编辑:正如 Russel 所说,facets 有一些隐藏的问题,并且与 ActiveSupport 的 API 不完全兼容。另一方面,ActiveSupport 并不像方面那么完整。最后,我会使用 AS 并让边缘情况出现在您的代码中。
You can use
except!
from thefacets
gem:The original hash does not change.
EDIT: as Russel says, facets has some hidden issues and is not completely API-compatible with ActiveSupport. On the other side ActiveSupport is not as complete as facets. In the end, I'd use AS and let the edge cases in your code.
您可以使用 如果您使用 Ruby 2,则进行了改进:
您可以使用此功能,而不会影响程序的其他部分,也不必包含大型外部库。
Instead of monkey patching or needlessly including large libraries, you can use refinements if you are using Ruby 2:
You can use this feature without affecting other parts of your program, or having to include large external libraries.
在纯红宝石中:
in pure Ruby:
请参阅 Ruby on Rails:删除多个哈希键
See Ruby on Rails: Delete multiple hash keys
使用
delete
、except
或except!
sample_hash = {hey: 'hey', hello: 'hello'}
删除:
返回键的值并删除原对象中的键,如果没有该键则返回nil
except:
返回不包含指定键的整个散列,但不更新原始散列
except!:
except!
与 except 相同,但它像所有 bang 操作方法一样永久更改原始哈希的状态Use
delete
,except
, orexcept!
sample_hash = {hey: 'hey', hello: 'hello'}
Delete:
Returns value of the key and deletes the key in the original object, returns nil if no such key
Except:
Returns the entire hash without the specified keys, but does not update the original hash
Except!:
except!
is the same as except but it permanently changes the state of the original hash like all bang operated methods do如果删除返回哈希的删除对,那就太好了。
我正在这样做:
It's was great if delete return the delete pair of the hash.
I'm doing this:
尝试使用
except!
方法。Try the
except!
method.我想删除键列表,并取回已删除的哈希“切片”:
Rails:
Pure Ruby:
I want to delete a list of keys, and get back the deleted "slice" of the hash:
Rails:
Pure Ruby:
这是一种单行的方法,但可读性不太好。建议使用两行代替。
This is a one line way to do it, but it's not very readable. Recommend using two lines instead.
多种方式删除Hash中的Key。
你可以使用下面的任何方法 方法
有很多,你可以查看 Hash 的 Ruby 文档 此处。
谢谢
Multiple ways to delete Key in Hash.
you can use any Method from below
So many ways is there, you can look on Ruby doc of Hash here.
Thank you
这也可以:
hash[hey] = nil
This would also work:
hash[hey] = nil