Код в вопросе (в частности, any?
) предполагает, что объект должен определить, существует ли для любого хеша h
в users
,
h[:gender] == city #=> true
или хешg
для которых:
g = h[:details]
g[:city] == city #=> true
Код
def city_present?(users, *key_groups, city)
key_arr = key_groups.map { |s| s.split('.').map(&:to_sym) }
users.any? { |h| key_arr.any? { |keys| h.dig(*keys) == city } }
end
Примеры
Для users
приведено ввопрос и
city_present?(users, "gender", "details.city", 'NY') #=> true
city_present?(users, "gender", "details.city", 'LA') #=> true
city_present?(users, "gender", "details.city", 'TO') #=> false
Пояснение
См. Hash # dig . key_arr
найдено равным:
[[:gender], [:details, :city]]
Повторные поиски
Принятие предложения @ ChrisHeald, если users
было большим, и должны были проводиться повторные поискидля разных значений имеет смысл создать набор значений, связанных с key_groups
. Это можно сделать следующим образом.
require 'set'
def values_present(users, *key_groups)
key_arr = key_groups.map { |s| s.split('.').map(&:to_sym) }
users.each_with_object(Set.new) do |h,set|
key_arr.each do |keys|
v = h.dig(*keys)
set << v unless v.nil?
end
end
end
values_present(users, "gender", "details.city")
#=> #<Set: {"Male", "NY", "Female", "LA"}>