Trier les objets par des valeurs booléennes dans Ruby
-
05-09-2019 - |
Question
Mes excuses si cela a été répondu avant ou est évident ... a-t-il fait une recherche ici et sur le goog et n'a pas trouvé de réponse.
Je cherche à trier un éventail de fournisseurs à prix et s'ils sont un privrable_provider? (vrai ou faux)
Par exemple dans array p of Providers
...
p1.price == 1, p1.preferred_provider? == false
p2.price == 2, p2.preferred_provider? == true
p2.price == 3, p3.preferred_provider? == true
Je voudrais p.sort_by et obtenir:
[p2 p3 p1]
Iaw
p.sort_by {|x| x.preferred_provider?, x.price }
ne fonctionne pas et obtient ...
undefined method `<=>' for false:FalseClass
Des suggestions sur de meilleures façons d'aborder ce problème?
La solution
La plupart des langues offrent des fonctions de tri qui acceptent comparateurs pour ce genre de chose. Dans Ruby, c'est juste Array.Sort:
p.sort {|a, b| if (a.preferred_provider? == b.preferred_provider?
then a.price <=> b.price
elsif a.preferred_provider?
1
else -1
}
Autres conseils
Vous pouvez définir un <=>
sur le Provider
classe pour faire ce que vous voulez, puis trier en utilisant le Array.sort
Méthode (plutôt que Enumerable.sort_by
). Voici une définition de <=>
que j'ai fouetté:
class Provider
def <=>(other)
if preferred_provider?
if other.preferred_provider?
@price <=> other.price
else
1
end
else
if other.preferred_provider?
-1
else
@price <=> other.price
end
end
end
end
Alors, si vous avez votre tableau p
, tu pourrais juste faire p_sorted = p.sort
.
(Notez que je n'ai pas testé ce code, il peut donc y avoir quelques erreurs, mais je pense qu'elle sert à démontrer l'idée.)