15

在“ Is it possible to sort a list of objects based on if the individual object's response to a method? ”中,我发现飞碟不适用于布尔值。

考虑:

红宝石 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

所谓的飞碟需要所有比较运算符(<, >, ==)才能工作(技术上不是,但理论上肯定是这样)。 true并且false不小于或大于彼此。对于nil. 对于实际的解决方法,您可以“强制转换”为整数(0 表示假,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 回答