2009-05-19 22 views

Respuesta

31

Sí, utilizando Array#sort! esto es fácil.

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

Thnx buddy pero no funcionó para mí tengo una matriz de objetos. En cuál de los atributos del objeto se crea_at. Quiero ordenarlo con este campo. así que lo hice @ comm_bytes.sort! {| a, b | a.created_at <=> b.created_at} pero no hubo suerte para mí ¿puedes ayudar ... ?? –

+3

¿Hay un método created_at para acceder al atributo @created_at? ¿Qué tipo de objeto es @created_at? ¿Define '<=>'? ¿Qué tipo de errores estás recibiendo? etc, etc., ad nauseum. En otras palabras, necesitamos más detalles que "pero sin suerte para mí". – rampion

+0

funciona si lo haces myarray = myarray.sort {...} sin "!" – DoruChidean

8

Matriz # tipo funciona bien, tal como fue anunciado anteriormente:

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

PERO, es necesario asegurarse de que el operador <=> se implementa para ese atributo. Si se trata de un tipo de datos nativo de Ruby, esto no es un problema. De lo contrario, escriba su propia implementación que devuelva -1 si es < b, 0 si son iguales, y 1 si a> b.

146

recomiendo el uso de sort_by lugar:

objects.sort_by {|obj| obj.attribute} 

Especialmente si el atributo se puede calcular.

+65

O la versión abreviada: 'objects.sort_by (&: attribute)' – Nikola

+3

objetos aún más cortos objects.sort_by &: attribute –

+1

Si tiene problemas con las letras mayúsculas y minúsculas que se ordenan por separado, puede usar 'objects.sort_by {| obj | obj.attribute.downcase} ' – campeterson

14

en caso de que necesite la clasificación por dos atributos, donde primero es más importante que el segundo (medios teniendo en cuenta segunda argumentos sólo si primeros argumentos son iguales), entonces es posible hacer como esto

myarray.sort{ |a,b| (a.attr1 == b.attr1) ? a.attr2 <=> b.attr2 : a.attr1 <=> b.attr1 } 

o en el caso de la matriz de matrices

myarray.sort{ |a,b| (a[0] == b[0]) ? a[1] <=> b[1] : a[0] <=> b[0] } 
+0

Hmmm ¡GRACIAS! – MrYoshiji

10

Usted puede hacer cualquier clase clasificable reemplazando el método < =>:

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 

Ahora una matriz de objetos Person se podrá ordenar en 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

Hay muchas respuestas idénticas publicadas en 2009. No es necesario agregar otra. – interjay

+2

No utilice 'sort' cuando esté ordenando objetos que no se pueden comparar directamente. Si tiene que acceder a los atributos o hacer un cálculo para obtener el valor para comparar use 'sort_by'. Será mucho más rápido. –

13

orden ascendente:

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

o

objects_array.sort_by{ |obj| obj.attribute } 

descendente orden:

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

o

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

más elegante objects.sort_by(&:attribute), se puede añadir un oon .reverse si necesita cambiar el orden.

Cuestiones relacionadas