从数组值中获取对应的键
Get corresponding key from an array value
我有一个哈希值是数组:
@@words = {
"direction" => ["north", "south", "west"],
"verb" => ["go", "jump"]
}
如果我做 @@words.key("north")
,它将 return error
而不是 direction
。我如何让它正常工作?
您可以使用Enumerable#select
@@words
=> {"direction"=>["north", "south", "west"], "verb"=>["go", "jump"]}
@@words.select { |_, v| v.include?("north") }
=> {"direction"=>["north", "south", "west"]}
@@words.select { |_, v| v.include?("north") }.keys
=> ["direction"]
map
的替代方案:
@@words.map { |k, v| k if v.include?("north") }.compact
=> ["direction"]
@@words.find { |_, value| value.include? 'north' }.first
@@words = {
"direction" => ["north", "south", "west"],
"verb" => ["go", "jump"]
}
@@words.find { |_,(v,*_)| v == "north" }
#=> ["direction", ["north", "south", "west"]]
or
@@words.find { |_,(v,*_)| v == "north" }.first
#=> "direction"
取决于您的要求。我假设 "north" 是值数组的第一个元素。
变体:
@@words.keys.find { |k| @@words[k].first == "north" }
您询问了以下中的块变量:
@@words.find { |_,(v,*_)| v == "north" }
我结合使用了并行赋值和分解(或消除歧义,这个词我觉得有点普通)。我们有:
enum = @@words.find
#=> #<Enumerator: {"direction"=>["north", "south", "west"],
# "verb"=>["go", "jump"]}:find>
enum
的两个元素将被传递到块中,可以通过将其转换为数组来查看:
enum.to_a
#=> [["direction", ["north", "south", "west"]],
# ["verb", ["go", "jump"]]]
当 enum
的第一个值传递给块时,块变量设置如下:
k,(v,*rest) = enum.next #=> ["direction", ["north", "south", "west"]]
k #=> "direction"
v #=> "north"
rest #=> ["south", "west"]
我不会在块计算中使用k
或rest
,所以我选择将两者替换为局部变量_
,主要是为了引起注意那些变量没有被使用的事实,也是为了减少块计算出错的机会。
顺便说一下,在 class 之外使用 class 变量是没有意义的,而且根本没有理由使用它。通常(总是?)使用 class 实例变量比 class 变量更可取。如果您不熟悉前者,那将是另一天的教训。
一些猴子补丁来拯救:-)
words = {
"direction" => ["north", "south", "west"],
"verb" => ["go", "jump"],
"test" => "me"
}
class Hash
def key_ (value)
key(value) || key(self.select { |k, v| v.include?(value)}.values.first)
end
end
puts words.key_("south") # direction
puts words.key_("go") # verb
puts words.key_("me") # test
self.select { |k, v| v.include?(value)}.values.first
表示其中存在 value
的数组,因此现在我们可以使用内置的 Hash#key
method 来查找密钥。
该代码还通过首先调用 key(value)
来处理 Hash 的值不全是数组的情况,如果是 nil
,则再次尝试认为可能是 value
作为数组成员出现在 Hash#values
之一中。
这个解决方案可以扩展到包括嵌套哈希和其他数据类型。
我有一个哈希值是数组:
@@words = {
"direction" => ["north", "south", "west"],
"verb" => ["go", "jump"]
}
如果我做 @@words.key("north")
,它将 return error
而不是 direction
。我如何让它正常工作?
您可以使用Enumerable#select
@@words
=> {"direction"=>["north", "south", "west"], "verb"=>["go", "jump"]}
@@words.select { |_, v| v.include?("north") }
=> {"direction"=>["north", "south", "west"]}
@@words.select { |_, v| v.include?("north") }.keys
=> ["direction"]
map
的替代方案:
@@words.map { |k, v| k if v.include?("north") }.compact
=> ["direction"]
@@words.find { |_, value| value.include? 'north' }.first
@@words = {
"direction" => ["north", "south", "west"],
"verb" => ["go", "jump"]
}
@@words.find { |_,(v,*_)| v == "north" }
#=> ["direction", ["north", "south", "west"]]
or
@@words.find { |_,(v,*_)| v == "north" }.first
#=> "direction"
取决于您的要求。我假设 "north" 是值数组的第一个元素。
变体:
@@words.keys.find { |k| @@words[k].first == "north" }
您询问了以下中的块变量:
@@words.find { |_,(v,*_)| v == "north" }
我结合使用了并行赋值和分解(或消除歧义,这个词我觉得有点普通)。我们有:
enum = @@words.find
#=> #<Enumerator: {"direction"=>["north", "south", "west"],
# "verb"=>["go", "jump"]}:find>
enum
的两个元素将被传递到块中,可以通过将其转换为数组来查看:
enum.to_a
#=> [["direction", ["north", "south", "west"]],
# ["verb", ["go", "jump"]]]
当 enum
的第一个值传递给块时,块变量设置如下:
k,(v,*rest) = enum.next #=> ["direction", ["north", "south", "west"]]
k #=> "direction"
v #=> "north"
rest #=> ["south", "west"]
我不会在块计算中使用k
或rest
,所以我选择将两者替换为局部变量_
,主要是为了引起注意那些变量没有被使用的事实,也是为了减少块计算出错的机会。
顺便说一下,在 class 之外使用 class 变量是没有意义的,而且根本没有理由使用它。通常(总是?)使用 class 实例变量比 class 变量更可取。如果您不熟悉前者,那将是另一天的教训。
一些猴子补丁来拯救:-)
words = {
"direction" => ["north", "south", "west"],
"verb" => ["go", "jump"],
"test" => "me"
}
class Hash
def key_ (value)
key(value) || key(self.select { |k, v| v.include?(value)}.values.first)
end
end
puts words.key_("south") # direction
puts words.key_("go") # verb
puts words.key_("me") # test
self.select { |k, v| v.include?(value)}.values.first
表示其中存在 value
的数组,因此现在我们可以使用内置的 Hash#key
method 来查找密钥。
该代码还通过首先调用 key(value)
来处理 Hash 的值不全是数组的情况,如果是 nil
,则再次尝试认为可能是 value
作为数组成员出现在 Hash#values
之一中。
这个解决方案可以扩展到包括嵌套哈希和其他数据类型。