web-dev-qa-db-ja.com

Rubyのオブジェクト属性によるオブジェクトの配列のソート?

Ruby on Railsにオブジェクトの配列があります。オブジェクトの属性で配列をソートしたいのですが、可能ですか?

112
Satyam Gautam

代わりにsort_byを使用することをお勧めします。

objects.sort_by {|obj| obj.attribute}

特に属性が計算される場合。

または、より簡潔なアプローチ:

objects.sort_by(&:attribute)
191
Scott

はい、 Array#sort! これは簡単です。

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

昇順 :

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
26
shiva kumar

最初の属性が2番目の属性よりも重要な2つの属性(最初の引数が等しい場合にのみ2番目の引数を考慮することを意味する)で並べ替える必要がある場合は、次のようにします。

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

<=>メソッドをオーバーライドすることにより、任意のクラスをソート可能にできます。

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

上記のように、Array#sortはうまく機能します。

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

ただし、<=>演算子がその属性に実装されています。 Rubyネイティブデータ型の場合、これは問題ではありません。それ以外の場合、a <bの場合-1、等しい場合0、および>の場合1を返す実装を記述しますb。

9
Curt J. Sampson

よりエレガントなobjects.sort_by(&:attribute)、追加できます.reverse順序を切り替える必要がある場合。

8
Noah Davis