1752


例えば、名前と給与を持つ`Employee`というクラスを定義し、これが基本的に`salary`でソートされるように、下のように実装したとします。

[code]

     class Employee < Struct.new(:name, :salary)
       def <=>(other)
         self.salary <=> other.salary
       end
     end
    
[/code]

このとき、

[code]

     employees = [Employee.new('foo', 100000),
                  Employee.new('bar', 150000),
                  Employee.new('esehara', 100000)]
    
     employees.sort.each do |people| 
       puts "名前: #{people.name}  給与: #{people.salary}円"
     end
    
[/code]

を実行した場合、出力は下のようになります:

[code]

    名前: foo  給与: 100000円
    名前: esehara  給与: 100000円
    名前: bar  給与: 150000円
    
[/code]

このとき、`salary`が同値だった場合、`name`のアルファベット順で並べたい(この場合ですと同じ給与である二人を、`esehara` ->
`foo`で並べたい)とした場合、`<=>`のオペレーター部分、あるいは他の場所にどのようなコードを書き足すべきなのでしょうか?


CC BY-SA 3.0
2014-12-16T11:10:43.923
1743
2014-12-16T12:15:23.143
939
question
ruby
<=>でソートされる順番を定義したときに、同値だった場合のさらなるソート順序を定義したい


`nonzero?` を使うと、望む動作になると思います。これは、非零の場合にはその値自身を、0 の場合には nil を返します。

[code]

    def <=>(other)
      (self.salary <=> other.salary).nonzero? ||
      (self.name <=> other.name)
    end
    
[/code]


CC BY-SA 3.0
2014-12-16T11:19:30.807
1744
2014-12-16T11:19:30.807
76
1743
answer


次の参考ページがあります。  
<https://stackoverflow.com/questions/4309723/ruby-sort-by-multiple-values>

これにしたがって質問文中のコードの def <=> 部分を次のように書き換えてみました。

[code]

    class Employee < Struct.new(:name, :salary)
      def <=>(other)
        [self.salary, self.name] <=> [other.salary, other.name]
      end
    end
    
    employees = [Employee.new('foo', 100000),
                 Employee.new('bar', 150000),
                 Employee.new('esehara', 100000)]
    
    employees.sort.each do |people|
      puts "名前: #{people.name}  給与: #{people.salary}円"
    end
    
[/code]

実行すると、次の実行結果がえられます。

[code]

    名前: esehara  給与: 100000円
    名前: foo  給与: 100000円
    名前: bar  給与: 150000円
    
[/code]


CC BY-SA 3.0
2014-12-16T12:15:23.143
1752
2014-12-16T12:15:23.143
2017-05-23T12:38:55.307
-1
2987
1743
answer