当前位置: 首页>>编程示例 >>用法及示例精选 >>正文


Ruby Range类用法及代码示例

本文简要介绍ruby语言中 Range类 的用法。

Range 对象表示介于给定开始值和结束值之间的值的集合。

您可以使用以下命令显式创建 Range 对象:

  • 一个range literal

    # Ranges that use '..' to include the given end value.
    (1..4).to_a      # => [1, 2, 3, 4]
    ('a'..'d').to_a  # => ["a", "b", "c", "d"]
    # Ranges that use '...' to exclude the given end value.
    (1...4).to_a     # => [1, 2, 3]
    ('a'...'d').to_a # => ["a", "b", "c"]

可以使用方法 Range.new 创建范围:

# Ranges that by default include the given end value.
Range.new(1, 4).to_a     # => [1, 2, 3, 4]
Range.new('a', 'd').to_a # => ["a", "b", "c", "d"]
# Ranges that use third argument +exclude_end+ to exclude the given end value.
Range.new(1, 4, true).to_a     # => [1, 2, 3]
Range.new('a', 'd', true).to_a # => ["a", "b", "c"]

无起点范围

beginless range 具有确定的结束值,但 nil 开始值。这样的范围包括直到最终值的所有值。

r = (..4)               # => nil..4
r.begin                 # => nil
r.include?(-50)         # => true
r.include?(4)           # => true

r = (...4)              # => nil...4
r.include?(4)           # => false

Range.new(nil, 4)       # => nil..4
Range.new(nil, 4, true) # => nil...4

无起始范围可用于对数组进行切片:

a = [1, 2, 3, 4]
r = (..2) # => nil...2
a[r]      # => [1, 2]

用于无开始范围的方法 each 会引发异常。

无尽的范围

endless range 有一个明确的开始值,但有一个 nil 结束值。这样的范围包括从开始值开始的所有值。

r = (1..)         # => 1..
r.end             # => nil
r.include?(50)    # => true

Range.new(1, nil) # => 1..

无限范围的文字可以用两个点或三个点来书写。无论哪种方式,该范围都具有相同的元素。但请注意,两者不相等:

r0 = (1..)           # => 1..
r1 = (1...)          # => 1...
r0.begin == r1.begin # => true
r0.end == r1.end     # => true
r0 == r1             # => false

无限范围可用于对数组进行切片:

a = [1, 2, 3, 4]
r = (2..) # => 2..
a[r]      # => [3, 4]

无限范围的方法 each 无限期地调用给定块:

a = []
r = (1..)
r.each do |i|
  a.push(i) if i.even?
  break if i > 10
end
a # => [2, 4, 6, 8, 10]

范围和其他类

如果对象的类实现实例方法 <=> ,则可以将对象放入范围中。这样做的 Ruby 核心类包括 Array , Complex , File::Stat , Float , Integer , Kernel , Module , Numeric , Rational , String , Symbol Time

例子:

t0 = Time.now         # => 2021-09-19 09:22:48.4854986 -0500
t1 = Time.now         # => 2021-09-19 09:22:56.0365079 -0500
t2 = Time.now         # => 2021-09-19 09:23:08.5263283 -0500
(t0..t2).include?(t1) # => true
(t0..t1).include?(t2) # => false

只有当其元素实现实例方法 succ 时,才能迭代范围。这样做的 Ruby 核心类包括 Integer String Symbol (但不包括上面提到的其他类)。

迭代器方法包括:

例子:

a = []
(1..4).each {|i| a.push(i) }
a # => [1, 2, 3, 4]

范围和用户定义的类

要在范围中使用的用户定义类必须实现实例 <=> ;见Integer#。为了使迭代可用,它还必须实现实例方法succ;见 Integer#succ

下面的类同时实现了 <=>succ ,因此可以用于构造范围和迭代它们。请注意,包含 Comparable 模块,因此 == 方法是根据 <=> 定义的。

# Represent a string of 'X' characters.
class Xs
  include Comparable
  attr_accessor :length
  def initialize(n)
    @length = n
  end
  def succ
    Xs.new(@length + 1)
  end
  def <=>(other)
    @length <=> other.length
  end
  def to_s
    sprintf "%2d #{inspect}", @length
  end
  def inspect
    'X' * @length
  end
end

r = Xs.new(3)..Xs.new(6) #=> XXX..XXXXXX
r.to_a                   #=> [XXX, XXXX, XXXXX, XXXXXX]
r.include?(Xs.new(5))    #=> true
r.include?(Xs.new(7))    #=> false

相关用法


注:本文由纯净天空筛选整理自ruby-lang.org大神的英文原创作品 Range类。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。