Tengo una gran variedad de objetos en Ruby on Rails. Quiero ordenar la matriz por un atributo del objeto. ¿Es posible?
Tengo una gran variedad de objetos en Ruby on Rails. Quiero ordenar la matriz por un atributo del objeto. ¿Es posible?
Respuestas:
Recomiendo usar sort_by en su lugar:
objects.sort_by {|obj| obj.attribute}
Especialmente si se puede calcular el atributo.
O un enfoque más conciso:
objects.sort_by(&:attribute)
objects.sort_by { |obj| obj.attribute.downcase }
sort!
(por ejemplo, velocidad, etc.)?
Sí, usar Array#sort!
esto es fácil.
myarray.sort! { |a, b| a.attribute <=> b.attribute }
<=>
? ¿Qué tipo de errores tienes? etc, etc, ad nauseum. En otras palabras, necesitamos más detalles que "pero no suerte para mí".
sort
si desea conservar el original y asignar el resultado a un objeto diferente; de otro modo, utilizar la variante en el lugar, sort!
. De hecho, sort
llama sort!
internamente, después de copiar el objeto original.
sort!
funcionará bien y siempre (!) Hacer lo mismo que ha escrito.
Orden ascendente:
objects_array.sort! { |a, b| a.attribute <=> b.attribute }
o
objects_array.sort_by{ |obj| obj.attribute }
Orden descendiente :
objects_array.sort! { |a, b| b.attribute <=> a.attribute }
o
objects_array.sort_by{ |obj| obj.attribute }.reverse
en caso de que necesite ordenar por dos atributos, donde el primero es más importante que el segundo (significa tener en cuenta los segundos argumentos solo si los primeros argumentos son iguales), entonces puede hacer esto
myarray.sort{ |a,b| (a.attr1 == b.attr1) ? a.attr2 <=> b.attr2 : a.attr1 <=> b.attr1 }
o en caso de una matriz de matrices
myarray.sort{ |a,b| (a[0] == b[0]) ? a[1] <=> b[1] : a[0] <=> b[0] }
Puede hacer que cualquier clase se pueda ordenar 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 <=>(other)
@last_name + @first_name <=> other.last_name + other.first_name
end
end
Ahora se podrá ordenar una matriz de objetos Persona 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" ]
Array # sort funciona bien, como se publicó anteriormente:
myarray.sort! { |a, b| a.attribute <=> b.attribute }
PERO, debe asegurarse de que el <=>
operador esté implementado para ese atributo. Si es un tipo de datos nativo de Ruby, esto no es un problema. De lo contrario, escriba su propia implementación que devuelva -1 si a <b, 0 si son iguales y 1 si a> b.
Más elegante objects.sort_by(&:attribute)
, puede agregar un .reverse
si necesita cambiar el orden.
@model_name.sort! { |a,b| a.attribute <=> b.attribute }
sort
cuando esté clasificando 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 el uso sort_by
. Será mucho más rápido
objects.sort_by(&:attribute)