如何在哈希数组中搜索哈希键值

4

我有一个哈希数组:

array = [
 {:name => "Bob" , :age => 27 , :place => "A"} ,
 {:name => "John" , :age => 50 , :place => "B"} ,
 {:name => "Alex" , :age => 80 , :place => "C"} 
]

如果:name == "John",我希望获得:place的值。

然而,如果我使用

array.find {|x| x[:name] == "John"}

我理解

{:name=>"John", :age=>"27", :place=>A}

我可以使用

array.second[:place]

这将返回 B,但数组中将有三个以上的哈希元素。

在另一个键的值的条件下,如何返回正确的位置?


1
你可以写 (array.find { |h| h["John"] } || {})["place"] 或者 array.find { |h| h["John"] }&.[]("place")&,即安全导航操作符,如果其前面的表达式返回nil,则整个表达式将返回nil&后必须跟一个句点,因此无法使用语法糖编写Hash#[]方法。或者,如果合适的话,可以为键:name没有值为"John"的哈希在数组中引发异常。 - Cary Swoveland
1
看起来你在错误的地方进行搜索。哈希数组看起来像是你从数据库请求了所有记录并试图对它们进行搜索,但你应该使用数据库查询来针对特定用户进行搜索。请参阅“什么是 XY 问题?”。 - the Tin Man
如果您经常这样做,您可能应该创建一个哈希表,以名称作为键,年龄和地点作为值。 - Eric Duminil
...@Eric,或者更一般地说,一个唯一标识符作为键。 - Cary Swoveland
@CarySwoveland:是的,但这对于按名称查找用户并没有太大帮助,不是吗? - Eric Duminil
1
@Eric,我在考虑大约翰•史密斯和小约翰•史密斯,但是是的。 - Cary Swoveland
3个回答

4
如果需要进行单个方法调用,他们可能会通过更早的返回来欺骗find
array.find { |h| break h[:place] if h[:name] == 'John' }
#⇒ "B"

总是在寻找作弊的方法...我从未见过这样的事情!有趣。 - Cary Swoveland
@CarySwoveland 好的,任何块中都可以字面上使用 breaknext - Aleksei Matiushkin
1
是的,但我觉得有趣的是将 break X 与块结合使用以避免在块后进行计算,并且如果条件为假,则块返回 nilfind - Cary Swoveland
2
@CarySwoveland 我的队友说接受我的PR的规则是:作弊次数应该是偶数,这样它们就会互相抵消。 - Aleksei Matiushkin

1

find 在您的情况下返回一个哈希表,只需传递键 :place 即可获取值:

hash = array.find {|x| x[:name] == "John"}
return if hash.nil?
hash[:place]

关于混合值的查询,我刚在IRB中尝试了一下,结果很好。

2.7.0 :014 > array = [
2.7.0 :015 >   {:name => "Bob" , :age => 27 , :place => "A"} ,
2.7.0 :016 >   {:name => "John" , :age => 50 , :place => "B"} ,
2.7.0 :017 >   {:name => "Alex" , :age => 80 , :place => "C"} 
2.7.0 :018 > ]
2.7.0 :019 > array.find {|x| x[:name] == "John"}
 => {:name=>"John", :age=>50, :place=>"B"} 

它返回了一个哈希值,但返回值是第一个数组和第二个数组的混合。 - Demi Dimitrova
我刚刚在我的irb中尝试了一下,它运行良好,我更新了我的答案。你还有其他事情要做吗? - Rajdeep Singh
在告诉我你一直在做和我完全相同的事情后,我注意到了一个我犯的笔误!谢谢你! :) - Demi Dimitrova
虽然我更喜欢在这里不显式检查 nil,但 return unless hash 就足够了。 - 3limin4t0r
array.find {|x| x[:name] == "John"}&.[](:place)虽然不太美观,但可以作为一行代码运行。 - Eric Duminil

0

这将返回该值:

 p array.find {|x| x[:name] == "John"}[:place]

创建一个方法并将"John"作为参数传递,以便您也可以获取其他名称的值。

2
当名称不存在于任何哈希表中时,它会返回什么? - Rajdeep Singh
他正在将模型哈希值提供给我们。 - Rajagopalan

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