2009-05-19 8 views

Répondre

31

Oui, en utilisant ce Array#sort! est facile.

myarray.sort! { |a, b| a.attribute <=> b.attribute } 
+0

Thnx mon pote mais ça n'a pas marché pour moi J'ai un tableau d'objets. Dans lequel l'un des attributs de l'objet est created_at. Je veux trier avec ce champ. donc j'ai fait @ comm_bytes.sort! {| a, b | a.created_at <=> b.created_at} mais pas de chance pour moi pouvez-vous aider .... ?? –

+3

Y a-t-il une méthode created_at pour accéder à l'attribut @created_at? Quel genre d'objet est @created_at? Définit-il '<=>'? Quel genre d'erreurs obtenez-vous? etc, etc, ad nausée. En d'autres termes, nous avons besoin de plus de détails que "mais pas de chance pour moi". – rampion

+0

cela fonctionne si vous faites myarray = myarray.sort {...} sans "!" – DoruChidean

8

Tableau # type fonctionne bien, comme affiché ci-dessus:

myarray.sort! { |a, b| a.attribute <=> b.attribute } 

Mais, vous devez vous assurer que l'opérateur <=> est mis en œuvre pour cet attribut. 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 < b, 0 si elles sont égales, et 1 si a> b.

146

Je recommande d'utiliser à la place sort_by:

objects.sort_by {|obj| obj.attribute} 

Surtout si l'attribut peut être calculé.

+65

Ou la version abrégée: 'objects.sort_by (&: attribute)' – Nikola

+3

Encore plus court objects.sort_by &: attribut –

+1

Si vous rencontrez des problèmes avec les majuscules et les minuscules triées séparément, vous pouvez utiliser 'objects.sort_by {| obj | obj.attribute.downcase} ' – campeterson

14

dans le cas où vous avez besoin de tri par deux attributs, où le premier est plus important que la deuxième (des moyens de prise en compte deuxième arguments que si les premiers arguments sont égaux), alors vous pouvez le faire comme ça

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] } 
+0

Hmmm MERCI! – MrYoshiji

10

Vous pouvez faire une classe sortable 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'objets Person sera triable 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" ] 
-1
@model_name.sort! { |a,b| a.attribute <=> b.attribute } 
+2

Il y a beaucoup de réponses identiques publiées en 2009. Pas besoin d'en ajouter une autre. – interjay

+2

N'utilisez pas 'sort' lorsque vous triez des objets qui ne peuvent pas être directement comparés. Si vous devez accéder à des attributs ou faire un calcul pour obtenir la valeur à comparer, utilisez 'sort_by'. Ce sera beaucoup plus rapide. –

13

ordre croissant:

objects_array.sort! { |a, b| a.attribute <=> b.attribute } 

ou

objects_array.sort_by{ |obj| obj.attribute } 

ordre décroissant:

objects_array.sort! { |a, b| b.attribute <=> a.attribute } 

ou

objects_array.sort_by{ |obj| obj.attribute }.reverse 
5

Plus élégant objects.sort_by(&:attribute), vous pouvez ajouter un oon .reverse si vous avez besoin de changer l'ordre.

Questions connexes