people.select {|person|
person.any? {|k, v|
%w[location hometown].include?(k) && /New York/ =~ v['name']
}}
Ceci dit essentiellement ce qui suit: sélectionnez toutes les entrées dans le tableau pour lequel la condition suivante est vraie. La condition est: est-il vrai pour l'une des paires clé-valeur que la clé est 'hometown'
ou 'location'
et la propriété name
de la valeur appartenant à cette clé correspond à l'expression rationnelle /New York/
? Toutefois, votre modèle d'objet semble avoir sérieusement besoin d'être refactorisé. En fait, le problème principal est que votre modèle d'objet n'est même pas un modèle d'objet, c'est un modèle de hachage et de tableau.
Voici ce que je veux dire par un modèle d'objet propre:
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]
Si vous avez un tel modèle d'objet propre, votre code devient beaucoup plus propre, car au lieu de taquineries à part les noix de Bults d'un labyrinthe imbriquée hash et les tableaux, vous avez de bons petits objets que vous pouvez simplement poser quelques questions:
people.select {|person| person.cities.any? {|city| city =~ /New York/ }}
vous pouvez presque lire cela comme l'anglais: à partir du tableau sélectionner toutes les personnes pour lesquelles correspond à la Regexp /New York/
une de leurs villes.
Si nous améliorons le modèle d'objet plus loin, il y a encore mieux:
class Person
def lived_in?(pattern)
cities.any? {|city| city =~ pattern }
end
end
people.select {|person| person.lived_in?(/New York/) }
Cela dit essentiellement « du peuple, sélectionnez ceux qui à un moment vécu à New York ». C'est beaucoup mieux que "des personnes sélectionnent tout pour lequel le premier élément de la paire valeur clé est soit la chaîne 'hometown'
ou la chaîne 'location'
et le deuxième élément de la paire de valeurs clés correspond à l'expression rationnelle /New York/
".
ce qui a été mis à jour – kylemac