people.select {|person|
person.any? {|k, v|
%w[location hometown].include?(k) && /New York/ =~ v['name']
}}
这基本上是这样说的:选择数组中的以下条件为真的所有条目。条件是:对于任何键值对,密钥是'hometown'
还是'location'
,属于该密钥的值的name
属性是否与正则表达式匹配/New York/
?
但是,您的对象模型似乎严重需要重构。事实上,主要的问题是你的对象模型甚至不是一个对象模型,它是一个散列和数组模型。
这里就是我的意思是通过适当的对象模型:因为不是戏弄分开的嵌套迷宫bults的坚果
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]
如果你有这样一个合适的对象模型,你的代码变得干净多了,哈希和数组,你有可爱的小物件,你可以简单地问几个问题:
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'
,并且键值对的第二个元素匹配正则表达式/New York/
”要好得多。
这已更新 – kylemac 2010-07-27 15:01:42