范围

范围 属于 Ruby

1 个练习

关于 范围

范围表示两个值之间的区间。 最常见的支持范围的类型是Integer和String。 它们有很多用途,比如快速创建集合、切分字符串、检查某个值是否在范围内,以及迭代。 范围使用运算符..或...创建(分别表示包含和不包含末尾值)。

1..5  # => 1..5
1...5 # => 1...5

(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]

之所以要有两种范围运算符,是为了让你能创建包含或不包含末尾值的范围。比如在处理从 0 开始的下标时,这一点就很有用。

也可以用Range初始化器来创建范围。

Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Note

在 Ruby 中用范围运算符..或...创建范围,并想在这个范围上调用方法时,需要把范围用括号括起来。 这是因为,如果不这样做,方法就会被调用在范围运算符的第二个参数上。

(1..5).sum # => 15
1..5.sum # => Error: undefined method `sum' for 5:Integer (NoMethodError)

获取子字符串

想切分字符串时,可以用范围运算符来获取子字符串。 也就是用子字符串的起始和结束下标创建一个范围。

"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"

你也可以使用负数下标,从字符串末尾开始获取子字符串。

"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"

范围方法

范围自带一组可用于操作它们的方法。 例如,可以用这些方法求范围内所有值的和,或者检查范围是否包含某个值。

方法 说明 示例
sum 返回范围内所有值的和 (1..5).sum # => 15
size 返回范围的大小 (1..5).size # => 5
include? 如果范围包含给定的值则返回true,否则返回false (1..5).include?(3) # => true

无终点和无起点的范围

范围可以没有终点,也可以没有起点。 无终点或无起点的范围,其起点或终点值是nil,但在定义范围时,这个nil可以省略。

无终点范围和无起点范围很有用,比如当你想要从字符串开头切分,或者切分到字符串末尾时。

"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello "
Caution

如果不是作用在集合上,无终点范围在不谨慎使用的情况下可能会产生无限序列。

字符串范围

字符串也可以用在范围中,让你得到两个字符串之间的一段字符串区间。 使用某些字符串时,它的行为可能有些出人意料,所以要谨慎使用。

"aa".."az".to_a # => ["aa", "ab", "ac", ..., "az"]

范围中的自定义对象

Advanced

Ruby 允许你在范围中使用自定义对象。 前提是该对象实现了以下内容:

  • 包含Comparable模块
  • succ方法
  • <=>方法

有了这些方法,范围就能迭代该对象,并比较范围内的对象。

class Foo
  include Comparable

  attr_reader :value

  def initialize(value)
    @value = value
  end

  def succ
    Foo.new(value + 1)
  end

  def <=>(other)
    value <=> other.value
  end
end

(Foo.new(1)..Foo.new(5))
# => #<Foo:0x7f3552bebe70 @value=1>, #<Foo:0x7f3552bebe50 @value=2>, #<Foo:0x7f3552bebe40 @value=3>, #<Foo:0x7f3552bebe30 @value=4>, #<Foo:0x7f3552bebe20 @value=5>
通过 GitHub 编辑 该链接会在新窗口或标签页中打开

学习 范围