15

メソッドに対する個々のオブジェクトの応答に応じて、オブジェクトのリストをソートすることは可能ですか?」で、空飛ぶ円盤がブール値で機能しないことを発見しました。

検討:

ルビー 1.8.7:

[true, false].sort # => undefined method `<=>' for true:TrueClass (NoMethodError)
true <=> false     # => undefined method `<=>' for true:TrueClass (NoMethodError)

ルビー 1.9.3:

[true, false].sort # => comparison of TrueClass with false failed (ArgumentError)
true <=> false     # => nil
true <=> true      # => 0
false <=> true     # => nil

true と false に正規の並べ替え順序がないことに関係している可能性があります。どちらが最初に来るのでしょうか? しかし、それは私にはかなり弱いように聞こえます。

これは のバグsortですか?

4

4 に答える 4

12

ブール値には自然順序付けはありません。

Ruby 言語の設計者は、おそらく、ブール値の順序付けを発明することは開発者にとって驚きであると感じたため、意図的に比較演算子を省略しました。

于 2013-02-11T16:29:27.860 に答える
8

いわゆる空飛ぶ円盤では、すべての比較演算子 ( <>==) が機能する必要があります (技術的にではありませんが、理論的には確かです)。 互いに小さくも大きくもありませんtruefalseについても同様ですnil。実際的な回避策として、整数に「キャスト」できます (false の場合は 0、true の場合は 1)。何かのようなもの:

[true, false, true].sort_by{|e| e ? 1 : 0}
于 2013-02-11T16:17:07.657 に答える
2

ブール値には自然な順序はありません。C とは異なり、false は true 未満ではなく、同等で等しく有効な状態です。ただし、ブロックを使用して好きなように並べ替えを構成することができます。たとえば、次のようになります。

ary = [true, false, false, true]
ary.sort {|a,b|  a == b ? 0 : a ? 1 : -1 }

# => [false, false, true, true]

順序を逆にすることも簡単です。

ary.sort {|a,b|  a == b ? 0 : a ? -1 : 1 }

# => [true, true, false, false]
于 2013-12-03T12:08:16.917 に答える
0

私はこれがかなり古いことを知っていますが、これは最近私を苦しめました。でもルビーですよね?このモンキーパッチをやってみませんか?

#! /usr/bin/env ruby

class TrueClass
  include Comparable

  def <=>(other)
    if other.class == FalseClass
      1
    elsif other.class == TrueClass
      0
    else
      nil
    end
  end
end

class FalseClass
  include Comparable

  def <=>(other)
    if other.class == TrueClass
      -1
    elsif other.class == FalseClass
      0
    else
      nil
    end
  end
end

puts "true <=> false: #{true <=> false}"
puts "false <=> true: #{false <=> true}"
puts "true <=> true: #{true <=> true}"
puts "false <=> false: #{false <=> false}"
puts "true <=> 13: #{true <=> 13}"
puts "true > false: #{true > false}"
puts "true < false: #{true < false}"
puts "true == false: #{true == false}"
puts "true == true: #{true == true}"
puts "false == false: #{false == false}"
puts "false < true: #{false < true}"
puts "[false, true, false].max: #{[false, true, false].max}"
puts "[false, true, false].min: #{[false, true, false].min}"
于 2022-01-21T10:23:03.487 に答える