Ruby 如何查找包含匹配值的哈希键

Ruby 如何查找包含匹配值的哈希键,ruby,Ruby,如果我有下面的客户端散列,有没有一种快速的ruby方法(无需编写多行脚本)来获取我想要匹配客户端id的密钥?例如,如何获取客户端的密钥\u id==“2180” 您可以使用: 请注意,结果将是所有匹配值的数组,其中每个值都是键和值的数组。尝试以下操作: clients.find{|key,value| value["client_id"] == "2178"}.first Ruby 1.9及更高版本: hash.key(value) => key Ruby 1.8: 你可以用 hsh.

如果我有下面的客户端散列,有没有一种快速的ruby方法(无需编写多行脚本)来获取我想要匹配客户端id的密钥?例如,如何获取
客户端的密钥\u id==“2180”

您可以使用:

请注意,结果将是所有匹配值的数组,其中每个值都是键和值的数组。

尝试以下操作:

clients.find{|key,value| value["client_id"] == "2178"}.first

Ruby 1.9及更高版本:

hash.key(value) => key
Ruby 1.8

你可以用

hsh.索引(值)=>key

返回给定值的键。如果 未找到,返回
nil

h={“a”=>100,“b”=>200}

h.index(200)#=>“b”

h.index(999)#=>nil

因此,要获得“橙色”,您可以使用:

clients.key({"client_id" => "2180"})

可以反转散列
clients.invert[“client\u id”=>“2180”]
返回
“orange”

您可以使用hashname.key(valuename)

或者,可能需要反转
new\u hash=hashname.invert
将为您提供一个
new\u hash
,让您可以更传统地做事。

来自文档:

  • (对象?)检测(ifnone=nil){| obj |…}
  • (对象?)查找(ifnone=nil){| obj |…}
  • (对象)检测(如果无=无)
  • (对象)查找(ifnone=nil)
将枚举中的每个项传递给块。返回块不为false的第一个块。如果没有匹配的对象,则调用ifnone并在指定时返回其结果,否则返回nil

如果没有给出块,则返回枚举数

(1..10).detect  {|i| i % 5 == 0 and i % 7 == 0 }   #=> nil
(1..100).detect {|i| i % 5 == 0 and i % 7 == 0 }   #=> 35
这对我很有用:

clients.detect{|client| client.last['client_id'] == '2180' } #=> ["orange", {"client_id"=>"2180"}] 

clients.detect{|client| client.last['client_id'] == '999999' } #=> nil 
见:

查找特定值的键的最佳方法是使用可用于散列的键方法

gender = {"MALE" => 1, "FEMALE" => 2}
gender.key(1) #=> MALE
我希望它能解决你的问题

根据ruby doc,key(value)是基于value查找键的方法

ROLE = {"customer" => 1, "designer" => 2, "admin" => 100}
ROLE.key(2)

它将返回“designer”。

我尝试的另一种方法是使用
#map

clients.map{ |key, _| key if clients[key] == {"client_id"=>"2180"} }.compact 
#=> ["orange"]

这将返回给定值的所有事件。下划线意味着我们不需要携带键的值,这样它就不会被分配给变量。如果值不匹配,数组将包含nils-这就是我将
#compact
放在末尾的原因。

以下是查找给定值的键的简单方法:

    clients = {
      "yellow"=>{"client_id"=>"2178"}, 
      "orange"=>{"client_id"=>"2180"}, 
      "red"=>{"client_id"=>"2179"}, 
      "blue"=>{"client_id"=>"2181"}
    }

    p clients.rassoc("client_id"=>"2180")
…并查找给定键的值:

    p clients.assoc("orange") 

它会给你一个键值对。

如果散列有多个键,这会有点混乱,因为你需要将整个散列赋给
索引
散列。在Ruby 1.9中,索引被重命名为
散列#key
,注意,如果有多个具有相同值的散列对,这只会返回第一个匹配,它将返回带有匹配值的第一个键。@Coderama
find
select
之间的区别是
find
返回第一个匹配项,
select
(别名为
findAll
)返回所有匹配项。我明白了,因此,对于存在多个匹配项的实例,这将是一个更安全的选项。这比创建一个全新的哈希(通过调用
invert
)来查找一个项要好。请注意,从开始,这将返回一个新的哈希和匹配项。它不会像在Ruby{“orange”=>{“client_id”=>“2180”}中那样返回数组
来获取密钥,简单地说就是
客户端。选择{key,hash | hash[“client_id”]==“2180”}。密钥
这似乎也是一种聪明的方法(因为它很短)!这就是我所需要的表单数组(用于选择框),它创建一个向后散列。如果find返回nil,这将引发一个异常,因为您无法调用.first on nil。如果使用Rails,您可以使用
。尝试(:first)
而不是
。first
以避免异常(如果您希望该值可能丢失)。在
Ruby 2.3.0+
中,您可以使用
&。首先,在块的末尾使用
来防止无异常。在Ruby的最新版本(1.9+)中,这是正确的方法。
#invert
在这种情况下是一个非常糟糕的主意,因为您本质上是为了查找密钥而为丢弃的哈希对象分配内存。根据散列大小,它会对性能产生严重影响
    clients = {
      "yellow"=>{"client_id"=>"2178"}, 
      "orange"=>{"client_id"=>"2180"}, 
      "red"=>{"client_id"=>"2179"}, 
      "blue"=>{"client_id"=>"2181"}
    }

    p clients.rassoc("client_id"=>"2180")
    p clients.assoc("orange")