我在 Ruby on Rails 中有一个对象数组。我想按对象的属性对数组进行排序。可以吗?
我建议使用 sort_by 代替:
objects.sort_by {|obj| obj.attribute}
特别是如果可以计算属性的话。
或者更简洁的方法:
objects.sort_by(&:attribute)
升序:
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 对象的数组将可以根据姓氏进行排序。
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, 0 if they are equal, and 1 if a > b. 返回 -1
我还想补充一下,如果你的属性可以为零:
如果您的属性是字符串:
objects_array.sort_by{ |obj| [ obj.attribute ? obj.attribute : "param_by_default".to_s ] }
如果您的属性是日期时间:
objects_array.sort_by{ |obj| [ obj.attr_time ? obj.attr_time : "06:00".to_datetime ] }
“06:00”-默认日期时间。
@model_name.sort! { |a,b| a.attribute <=> b.attribute }