J’ai un tableau d’objects dans Ruby on Rails. Je veux sortinger le tableau par un atsortingbut de l’object. C’est possible?
Je recommande d’utiliser sort_by à la place:
objects.sort_by {|obj| obj.atsortingbute}
Surtout si l’atsortingbut peut être calculé.
Oui, en utilisant Array#sort!
c’est facile.
myarray.sort! { |a, b| a.atsortingbute <=> b.atsortingbute }
Ordre croissant :
objects_array.sort! { |a, b| a.atsortingbute <=> b.atsortingbute }
ou
objects_array.sort_by{ |obj| obj.atsortingbute }
Ordre décroissant :
objects_array.sort! { |a, b| b.atsortingbute <=> a.atsortingbute }
ou
objects_array.sort_by{ |obj| obj.atsortingbute }.reverse
au cas où vous auriez besoin de sortinger par deux atsortingbuts, le premier étant plus important que le second (cela signifie prendre en compte les deuxièmes arguments uniquement si les premiers arguments sont égaux), alors vous pouvez faire comme ceci
myarray.sort{ |a,b| (a.attr1 == b.attr1) ? a.attr2 <=> b.attr2 : a.attr1 <=> b.attr1 }
ou en cas de tableau de tableaux
myarray.sort{ |a,b| (a[0] == b[0]) ? a[1] <=> b[1] : a[0] <=> b[0] }
Vous pouvez rendre toute classe sortingable en remplaçant la méthode <=>:
class Person attr_accessor :first_name, :last_name def initialize(first_name, last_name) @first_name = first_name @last_name = last_name end def <=>(per) @last_name + @first_name <=> per.last_name + per.first_name end end
Maintenant, un tableau d’objects Person sera sortingable sur last_name.
ar = [Person.new("Eric", "Cunningham"), Person.new("Homer", "Allen")] puts ar # => [ "Eric Cunningham", "Homer Allen"] (Person objects!) ar.sort! puts ar # => [ "Homer Allen", "Eric Cunningham" ]
Array # sort fonctionne bien, comme indiqué ci-dessus:
myarray.sort! { |a, b| a.atsortingbute <=> b.atsortingbute }
MAIS, vous devez vous assurer que l’opérateur <=>
est implémenté pour cet atsortingbut. Si c’est un type de données natif Ruby, ce n’est pas un problème. Sinon, écrivez votre propre implémentation qui renvoie -1 si a b.
Plus élégant objects.sort_by(&:atsortingbute)
, vous pouvez append un .reverse
si vous devez changer l’ordre.
@model_name.sort! { |a,b| a.atsortingbute <=> b.atsortingbute }