【发布时间】:2010-10-27 07:02:45
【问题描述】:
我在 Ruby on Rails 中有一个对象数组。我想按对象的属性对数组进行排序。有可能吗?
【问题讨论】:
我在 Ruby on Rails 中有一个对象数组。我想按对象的属性对数组进行排序。有可能吗?
【问题讨论】:
我建议改用 sort_by:
objects.sort_by {|obj| obj.attribute}
特别是如果可以计算属性。
或者更简洁的方法:
objects.sort_by(&: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" ]
【讨论】:
更优雅的objects.sort_by(&:attribute),如果需要切换顺序可以加.reverse。
【讨论】:
Array#sort 效果很好,如上所述:
myarray.sort! { |a, b| a.attribute <=> b.attribute }
但是,您需要确保为该属性实现了 <=> 运算符。如果它是 Ruby 原生数据类型,这不是问题。否则,编写您自己的实现,如果 a b 返回 1。
【讨论】:
@model_name.sort! { |a,b| a.attribute <=> b.attribute }
【讨论】:
sort。如果您必须访问属性或进行计算以获取要比较的值,请使用sort_by。它会快得多。