3

是否可以在 ruby​​ 中创建排除一个或两个端点的范围。那么处理开闭区间边界的数学概念呢?

例如,我能否定义一个从 1.0 到 10.0 的范围,不包括 1.0

说(用伪红宝石)

range = [1.0...10.0)

range === 1.0
=> false

range === 10.0
=> true
4

4 回答 4

7

Ruby 中的Range类仅支持封闭和半开(右开)范围。但是,您可以轻松编写自己的代码。

这是 Ruby 中的半开范围示例:

range = 1.0...10.0

range === 1.0
# => true

range === 10.0
# => false

Rubinius 中符合 Ruby 1.9 的Range类的总行数为 238 行 Ruby 代码。如果你不需要你的开放范围类来支持 Ruby 语言规范的每一个皱纹、极端情况、特殊情况、特质、向后兼容怪癖等等,那么你可以用比这少得多的东西来解决问题。

如果你真的只需要测试包含,那么这样的事情就足够了:

class OpenRange
  attr_reader :first, :last

  def initialize(first, last, exclusion = {})
    exclusion = { first: false, last: false }.merge(exclusion)
    @first, @last, @first_exclusive, @last_exclusive = first, last, exclusion[:first], exclusion[:last]
  end

  def first_exclusive?; @first_exclusive end
  def last_exclusive?;  @last_exclusive  end

  def include?(other)
    case [first_exclusive?, last_exclusive?]
    when [true,  true]
      first <  other && other <  last
    when [true,  false]
      first <  other && other <= last
    when [false, true]
      first <= other && other <  last
    when [false, false]
      first <= other && other <= last
    end
  end

  alias_method :===, :include?

  def to_s
    "#{if first_exclusive? then '(' else '[' end}#@first...#@last#{if last_exclusive? then ')' else ']' end}"
  end

  alias_method :inspect, :to_s
end
于 2012-09-19T11:04:29.323 回答
5

您可以使用 排除范围的最右边的元素...。请参阅下面的示例

(1..10).to_a # an array of numbers from 1 to 10 - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

(1...10).to_a # an array of numbers from 1 to 9 - [1, 2, 3, 4, 5, 6, 7, 8, 9]
于 2012-09-19T11:04:06.150 回答
4

使用从头到尾运行构建..的范围。那些使用...不包括最终值创建的。

('a'..'e').to_a    #=> ["a", "b", "c", "d", "e"]
('a'...'e').to_a   #=> ["a", "b", "c", "d"]

在这里查看更多

您也可以轻松编写自己的 Range 来排除起始值。

对于浮动范围:

(1.0..10.0).step.to_a # => [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
(1.0...10.0).step.to_a # => [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
(1.0..10.0).step(2.0).to_a # => [1.0, 3.0, 5.0, 7.0, 9.0]
(1.0...10.0).step(2.0).to_a # => [1.0, 3.0, 5.0, 7.0, 9.0]
于 2012-09-19T11:05:22.193 回答
0

几年后但是......利用案例陈述按出现顺序评估每个标准并根据其第一次匹配遵循路径的事实怎么样。在示例中,1.0 总是什么都不做,即使它在技术上是第二个“when”的有效值。

case myvalue
    when 1.0
      #Don't do anything (or do something else)
    when 1.0...10.0
      #Do whatever you do when value is inside range 
      # not inclusive of either end point
    when 10.0
      #Do whatever when 10.0 or greater
    end
于 2015-03-15T17:47:49.883 回答