people.select {|person|
person.any? {|k, v|
%w[location hometown].include?(k) && /New York/ =~ v['name']
}}
В основном это говорит о следующем: выберите все записи в массиве, для которых выполняется следующее условие. Условие: верно ли для любой из пар ключ-значение, что ключ является либо 'hometown'
, либо 'location'
, а свойство name
значения, принадлежащего этому ключу, соответствует Regexp /New York/
?
Однако ваша объектная модель, похоже, серьезно нуждается в рефакторинге. На самом деле главная проблема в том, что ваша объектная модель - это даже не объектная модель, это модель хешей и массивов.
Вот что я имею в виду под правильной объектной моделью:
class Person
attr_reader :name, :location, :hometown
def initialize(name, location=nil, hometown=nil)
@name, @location, @hometown = name, location, hometown
end
def cities
return @location, @hometown
end
end
class City
attr_reader :id, :name
def initialize(id, name)
@id, @name = id, name
end
def =~(other)
name =~ other
end
end
nyc = City.new(12746342329, 'New York, New York')
brooklyn = City.new(43453644, 'Brooklyn, New York')
miami = City.new(12746342329, 'Miami, Florida')
queens = City.new(12746329, 'Queens, New York')
john = Person.new('John Doe', nyc, brooklyn)
jane = Person.new('Jane Doe', miami, queens)
people = [john, jane]
Если у вас есть такая подходящая объектная модель, ваш код становится намного чище, потому что вместо того, чтобы разбирать гайки на части вложенного лабиринта хешей и массивов, у вас есть красивые маленькие объекты, которые вы можете просто задать несколько вопросов: 1013 *
people.select {|person| person.cities.any? {|city| city =~ /New York/ }}
Вы можете почти прочитать это как английский: из массива выберите всех людей, для которых любой из их городов соответствует регулярному выражению /New York/
.
Если мы продолжим улучшать объектную модель, она станет еще лучше:
class Person
def lived_in?(pattern)
cities.any? {|city| city =~ pattern }
end
end
people.select {|person| person.lived_in?(/New York/) }
Это в основном говорит: «Из людей, выберите тех, которые когда-то жили в Нью-Йорке». Это гораздо лучше, чем «из людей, выбирающих все, для которых первый элемент пары ключ-значение является либо строкой 'hometown'
, либо строкой 'location'
, а второй элемент пары« ключ-значение »совпадает с Regexp /New York/
».