У меня есть массив объектов в Ruby on Rails. Я хочу отсортировать массив по атрибуту объекта. Является ли это возможным?
У меня есть массив объектов в Ruby on Rails. Я хочу отсортировать массив по атрибуту объекта. Является ли это возможным?
Ответы:
Вместо этого я рекомендую использовать sort_by:
objects.sort_by {|obj| obj.attribute}
Особенно, если атрибут можно вычислить.
Или более лаконичный подход:
objects.sort_by(&:attribute)
objects.sort_by { |obj| obj.attribute.downcase }
sort!
(например, скорость и т. Д.)?
Да, использовать Array#sort!
это просто.
myarray.sort! { |a, b| a.attribute <=> b.attribute }
<=>
? Какие ошибки вы получаете? и т. д. и т. д. до тошноты. Другими словами, нам нужно больше деталей, чем «но мне не повезло».
sort
если хотите сохранить оригинал и присвоить результат другому объекту; в противном случае используйте вариант в месте, sort!
. Фактически, sort
вызывает sort!
внутренний вызов после копирования исходного объекта.
sort!
будет работать нормально и всегда (!) Делать то же самое, что вы написали.
По возрастанию:
objects_array.sort! { |a, b| a.attribute <=> b.attribute }
или
objects_array.sort_by{ |obj| obj.attribute }
В порядке убывания :
objects_array.sort! { |a, b| b.attribute <=> a.attribute }
или
objects_array.sort_by{ |obj| obj.attribute }.reverse
если вам нужна сортировка по двум атрибутам, где первый важнее, затем второй (означает учет вторых аргументов, только если первые аргументы равны), тогда вы можете сделать это
myarray.sort{ |a,b| (a.attr1 == b.attr1) ? a.attr2 <=> b.attr2 : a.attr1 <=> b.attr1 }
или в случае массива массивов
myarray.sort{ |a,b| (a[0] == b[0]) ? a[1] <=> b[1] : a[0] <=> b[0] }
Вы можете сделать любой класс сортируемым, переопределив метод <=>:
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
Теперь массив объектов Person можно будет отсортировать по 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 работает хорошо, как указано выше:
myarray.sort! { |a, b| a.attribute <=> b.attribute }
НО, вам нужно убедиться, что <=>
оператор реализован для этого атрибута. Если это собственный тип данных Ruby, это не проблема. В противном случае напишите собственную реализацию, которая возвращает -1, если a <b, 0, если они равны, и 1, если a> b.
@model_name.sort! { |a,b| a.attribute <=> b.attribute }
sort
при сортировке объектов, которые нельзя сравнивать напрямую. Если вам нужно получить доступ к атрибутам или выполнить вычисление, чтобы получить значение для сравнения, используйте sort_by
. Будет намного быстрее.
objects.sort_by(&:attribute)