Ruby-on-rails 如何一次获取多个哈希值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17646643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I fetch multiple hash values at once?
提问by Dmytrii Nagirniak
What is a shorter version of this?:
更短的版本是什么?:
from = hash.fetch(:from)
to = hash.fetch(:to)
name = hash.fetch(:name)
# etc
Note the fetch, I want to raise an error if the key doesn't exist.
请注意fetch,如果密钥不存在,我想引发错误。
There must be shorter version of it, like:
它必须有更短的版本,例如:
from, to, name = hash.fetch(:from, :to, :name) # <-- imaginary won't work
It is OK to use ActiveSupport if required.
如果需要,可以使用 ActiveSupport。
回答by Dylan Markow
回答by matthew.tuck
Ruby 2.3 finally introduces the fetch_valuesmethod for hashes that straightforwardly achieves this:
Ruby 2.3 终于引入了fetch_values直接实现这一点的散列方法:
{a: 1, b: 2}.fetch_values(:a, :b)
# => [1, 2]
{a: 1, b: 2}.fetch_values(:a, :c)
# => KeyError: key not found: :c
回答by sawa
hash = {from: :foo, to: :bar, name: :buz}
[:from, :to, :name].map{|sym| hash.fetch(sym)}
# => [:foo, :bar, :buz]
[:frog, :to, :name].map{|sym| hash.fetch(sym)}
# => KeyError
回答by vgoff
my_array = {from: 'Jamaica', to: 'St. Martin'}.values_at(:from, :to, :name)
my_array.keys.any? {|key| element.nil?} && raise || my_array
This will raise an error like you requested
这将引发您要求的错误
my_array = {from: 'Jamaica', to: 'St. Martin', name: 'George'}.values_at(:from, :to, :name)
my_array.keys.any? {|key| element.nil?} && raise || my_array
This will return the array.
这将返回数组。
But OP asked for failing on a missing key...
但是 OP 要求在丢失的钥匙上失败......
class MissingKeyError < StandardError
end
my_hash = {from: 'Jamaica', to: 'St. Martin', name: 'George'}
my_array = my_hash.values_at(:from, :to, :name)
my_hash.keys.to_a == [:from, :to, :name] or raise MissingKeyError
my_hash = {from: 'Jamaica', to: 'St. Martin'}
my_array = my_hash.values_at(:from, :to, :name)
my_hash.keys.to_a == [:from, :to, :name] or raise MissingKeyError
回答by Alistair A. Israel
The simplest thing I would go for would be
我会做的最简单的事情是
from, to, name = [:from, :to, :name].map {|key| hash.fetch(key)}
Alternatively, if you want to use values_at, you can use a Hashwith a default value block:
或者,如果您想使用values_at,您可以使用Hash带有默认值块的 a:
hash=Hash.new {|h, k| raise KeyError.new("key not found: #{k.inspect}") }
# ... populate hash
from, to, name = hash.values_at(:from, :to, :name) # raises KeyError on missing key
Or, if you're so inclined, monkey-patch Hash
或者,如果你如此倾向,猴子补丁 Hash
class ::Hash
def fetch_all(*args)
args.map {|key| fetch(key)}
end
end
from, to, name = hash.fetch_all :from, :to, :name
回答by saihgala
You could initialise your hash with a default value of KeyErrorobject. This will return an instance of KeyError if the key you are trying to fetch is not present. All you need to do then is check its (value's) class and raise it if its a KeyError.
您可以使用KeyError对象的默认值初始化您的哈希。如果您尝试获取的密钥不存在,这将返回一个 KeyError 实例。然后你需要做的就是检查它的(值的)类,如果它是一个 KeyError 则提高它。
hash = Hash.new(KeyError.new("key not found"))
Let's add some data to this hash
让我们向这个哈希添加一些数据
hash[:a], hash[:b], hash[:c] = "Foo", "Bar", nil
Finally look at the values and raise an error if key not found
最后查看值并在未找到键时引发错误
hash.values_at(:a,:b,:c,:d).each {|v| raise v if v.class == KeyError}
This will raise an exception if and only if key is not present. It'll not complain in case you have a key with nilvalue.
当且仅当 key 不存在时,这才会引发异常。如果你有一个nil有价值的键,它不会抱怨。

