5

Fruitと呼ばれる構造体のリストがありbasketます。各Fruit構造体にはname(文字列)とcalories(整数)があります。次のように並べ替えたいと思いますbasket

  1. 最もFruit高いscaloriesが最初に表示されます。たとえば、500カロリーの果物は、400カロリーの果物の前に表示されます。

  2. 2つFruitのsが等しい場合calories、大文字と小文字を区別せずに、アルファベット順で最初に来るものが最初にFruitなります。nameたとえば、カロリーが等しい2つの果物を考えると、「バナナ」という名前の果物が「柑橘類」という名前の果物の前に来ることになります。

の定義はFruit私が制御するものではないので、何かを混ぜFruitたり変更したりすることを含まないソリューションを好みます。これは可能ですか?

4

4 に答える 4

12

簡単な解決策は

basket.sort_by { |f| [-f.calories, f.name] }

もちろん、これが果物標準的な並べ替え順序である場合は、メソッドを使用して、モジュールをに混合して定義する必要があります<=>ComparableFruit

于 2009-05-12T13:18:40.223 に答える
2

バスケットが配列またはそのサブクラスであると仮定しましょう。

ファストウェイ

Enumerable.sort_by

Garethが指摘したように、Enumerable(Arrayに含まれている)には、各リスト項目を1回実行する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ウェイ

Array.sort

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
}
于 2009-05-12T13:19:57.740 に答える
1

Array#sortAPIドキュメント)を参照してください。2つのオブジェクトを指定して-1、0、または1を返すブロックを渡すことができ、Fruitブロックは任意の属性を使用してこれらの値を決定できます。

于 2009-05-12T13:18:12.907 に答える
1

果物をたくさん並べ替える必要がある場合は、おそらく前もってもう少し作業を行い、オブジェクトを比較できるようにする必要があります。

このためには、Spaceship-Operator ( <=>) を実装し、Comparable を含める必要があります。

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

Comparable は他にも多くのメソッド ( ==<>) を無料で提供するので、次のようなことができます if (apple < banana)(詳細については、Comparable モジュールのドキュメントを参照してください)。

<=> は、が より小さい場合、 が小さい場合、および両方のオブジェクトが等しい場合に返す-1ように指定されています。selfother+1other0

于 2009-05-12T19:57:24.910 に答える