在 Ruby 中按对象属性对对象数组进行排序?

问题描述 投票:0回答:10

我在 Ruby on Rails 中有一个对象数组。我想按对象的属性对数组进行排序。可以吗?

ruby sorting object
10个回答
273
投票

我建议使用 sort_by 代替:

objects.sort_by {|obj| obj.attribute}

特别是如果可以计算属性的话。

或者更简洁的方法:

objects.sort_by(&:attribute)

38
投票

升序:

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

37
投票

是的,使用

Array#sort!
这很简单。

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

21
投票

如果您需要按两个属性排序,其中第一个属性比第二个更重要(意味着仅当第一个参数相等时才考虑第二个参数),那么您可以这样做

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] }

19
投票

您可以通过重写 <=> 方法使任何类可排序:

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" ]

12
投票

更优雅

objects.sort_by(&:attribute)
,如果需要切换顺序可以加一个
.reverse


10
投票

Array#sort 效果很好,如上面发布的:

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

但是,您需要确保为该属性实现了

<=>
运算符。如果它是 Ruby 本机数据类型,那么这不是问题。否则,编写您自己的实现,如果 a < b, 0 if they are equal, and 1 if a > b.

返回 -1

0
投票

我还想补充一下,如果你的属性可以为零:

如果您的属性是字符串:

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”-默认日期时间。



-2
投票
@model_name.sort! { |a,b| a.attribute <=> b.attribute }
© www.soinside.com 2019 - 2024. All rights reserved.