在哈希表中查找数组中值的键

4

我有一个哈希表,内容如下:

categories = {"horeca" => ["bar", "waiter", "kitchen"], 
              "retail" => ["eerste", "tweede"]}

我希望能够在一个值的数组中查找是否包含某个键,类似于以下内容:
categories.key("bar")

这将返回"horeca"。

目前只有当我执行以下操作时才能获得"horeca"。

categories.key(["bar", "waiter", "kitchen"])

我从未使用过Ruby编程语言,但是创建第二个哈希映射表并插入(bar,horeca),(waiter,horeca)等相反的键值对,是否可能呢?然后,您就可以轻松地执行所需的查询了。 - TimD1
你想返回包含“bar”的值数组的第一个键还是所有键? - Sagar Pandya
4个回答

7
尝试使用 Enumberable#find 方法:
categories.find { |key, values|
  values.include?("bar")
}.first

1
在哈希上调用 find 会返回一个 [key, value] 对。要获取键,需要调用 first - Mate Solymosi

5
正如Máté提到的,如果您想要查找第一个匹配元素,可以使用find。如果您想要所有匹配的元素,请使用select。要获取键,只需执行以下操作:
categories.select { |key, values| values.include?("bar") }.map(&:first)

请查看https://ruby-doc.org/core-2.2.3/Enumerable.html#method-i-select


你可以使用 keys 替代 map(&:first) - Sagar Pandya
不幸的是,这并不起作用,因为你没有返回哈希,而是像这样的二维数组:[["first", ["bar", "baz"]], ["second", ["not bar", "baz"]]] - tpei

3
创建中间数组,然后调用其第一个元素是不必要的。此外,如果哈希表很大,并且您想要匹配的第一个值,则以下解决方案更好:
categories.each{ |k,v| break k if v.include?('bar') }
#=> "horeca"

3

Md. Farhan Memon的解决方案通常是首选方案,但它有一个缺点:如果集合中没有匹配项,则返回整个集合,这可能不是一个理想的结果。您可以通过简单的调整来结合detect/findbreak来解决这个问题:

categories.detect { |key, values| break key if values.include?('bar') }

如果找到该值,则会中断并返回该值,否则将返回nil(我认为这是更可取的行为)。

如果您的集合还可能包含nil值和/或非数组,则可以进一步改进:

categories.detect { |key, values| break key if Array(values).include?('bar') }

这种通用方法的唯一缺点是对于新手来说不太直观:在运行代码之前,你需要知道比基础的 Ruby 更多的东西才能理解正在发生的事情。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接