从数组值中获取相应的键

时间:2015-08-25 18:46:36

标签: arrays ruby hash key

我有一个散列,其值为数组:

@@words = {
    "direction" => ["north", "south", "west"],
    "verb" => ["go", "jump"]
  }

如果我@@words.key("north"),则会返回error而不是direction。如何让它正常工作?

4 个答案:

答案 0 :(得分:4)

@@words.find { |_, value| value.include? 'north' }.first

答案 1 :(得分:4)

@@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"

取决于您的要求。我假设"北"是要成为数组数组的第一个元素。

变体:

@@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"] 

我在块计算中不会使用krest,所以我选择用局部变量_替换它们,主要是为了绘制注意那些变量没有被使用的事实,也是为了减少块计算中出错的几率。

顺便说一句,在类之外使用类变量是没有意义的,根本没有理由使用类变量。它通常(总是?)比使用类变量更可取。如果你不熟悉前者,那将是另一天的教训。

答案 2 :(得分:1)

您可以使用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"]

答案 3 :(得分:0)

一些猴子修补救援: - )

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来查找密钥。

当Hash的值不是所有数组时,代码还会通过首先调用key(value)来处理场景,如果它是nil,那么它再次尝试思考可能是value作为数组成员存在于Hash#values之一。

此解决方案可以扩展为包含嵌套哈希和其他数据类型。

相关问题