質問
私の一覧 Fruit
構造体と呼ばれ basket
.各 Fruit
構造体は、 name
(文字列) calories
(整数).思う basket
るものとする。
の
Fruit
s最高calories
表示されます。例えば、フルーツ500カロリーが表示される前にフルーツ400いる。さ
Fruit
sに等しいcalories
, は、Fruit
そのname
第一アルファベット順が、無視します。例えば、二つの成果と同等のカロリー名を"バナナ"が来る前に名を柑橘".
のの定義 Fruit
というのはいっていうソリューションになる混合も Fruit
-変更します。可能ですか?
解決
簡単な解決策がある。
basket.sort_by { |f| [-f.calories, f.name] }
この果実は、 の正規ソート順序である場合は、もちろん、それ
<=>
法を使用して定義し、Comparable
に混合Fruit
モジュールとすべきです 他のヒント
のは、バスケットが配列またはそのサブクラスであると仮定しよう。
高速道
ガレスには指摘したように、、(配列によって含まれる)列挙は、一旦各リスト項目を通るsort_byメソッドを有します。これは、あなたがそれのこつを得れば書くために実行し、より速くするために高速です。
# -f.calories to sort descending
# name.downcase to do a case-insensitive sort
basket = basket.sort_by { |f| [-f.calories, f.name.downcase] }
Perlの道
Perlの背景から来て、私の最初の衝動は、宇宙船のオペレータ<=>をつかむことです。生意気な小悪魔。配列はソートし、ソートしています!それは非常に有用なものにする方法。このソリューションは遅くなり、そしてそれは長いですので、バグを導入する可能性が高いです。あなたはRubyのに慣れていないとのStackOverflow上の右の方法を見つけるために不本意人々を扱っている場合は、それを使用する唯一の理由です。
baseket.sort! { |a,b|
if a.calories == b.calories
a.name.downcase <=> b.name.downcase
else
# Reverse the result to sort highest first.
-(a.calories <=> b.calories)
end
}
Array#sort
( APIドキュメントを)を参照してください。あなたは、-1を返しブロックに0を渡すことができ、または1つの与えられた2つのFruit
オブジェクト、そしてあなたのブロックは、あなたが喜ば属性を何でも使ってこれらの値を決定することができます。
が必要な場合はソ果物を多くるべきだ少し前に、体に匹敵します。
このために必要なものimplmentの宇宙船-オペレーター(<=>
などに匹敵します。
class Fruit
attr_accessor :name, :color
def <=>(other)
# use Array#<=> to compare the attributes
[self.name.downcase, self.color] <=> [other.name.downcase, other.color]
end
include Comparable
end
そのように:
list_of_fruits.sort
比較ものが多くその他の方法==
, <
, >
用可能になっていますように if (apple < banana)
参照 ドキュメンテーションには同モジュール のための詳細情報)
<=>定を返す -1
の場合 self
より小さく other
, +1
の場合 other
が小さく、 0
場合はオブジェクトが等しい