範囲

範囲 の Ruby

1個の演習

範囲について

範囲は、2つの値の間の区間を表します。 範囲をサポートする最も一般的な型は、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]

範囲演算子が2つあるのは、終端の値を含む範囲と含まない範囲の両方を作れるようにするためです。これは例えば、0から始まるインデックスを扱うときに便利です。

範囲は、Rangeのイニシャライザーを使って作ることもできます。

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

Rubyで範囲演算子..や...を使って範囲を作り、その範囲に対してメソッドを呼び出したいときは、範囲を括弧で囲む必要があります。 そうしないと、メソッドは範囲演算子の2番目の引数に対して呼び出されてしまうからです。

(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

コレクションに対して使わない場合、終端のない範囲は、注意して使わないと終わりのない繰り返しを引き起こすことがあります。

文字列の範囲

範囲には文字列も使えて、2つの文字列の間にある文字列の区間を取得できます。 特定の文字列を使うと動作が少し予想外になることがあるので、注意して使ってください。

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

範囲で使う独自のオブジェクト

Advanced

Rubyでは、独自のオブジェクトを範囲に使えます。 そのための条件は、オブジェクトが次のものを実装していることです。

  • Comparableモジュールをincludeしていること
  • 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で編集 リンクは新しいウィンドウまたはタブで開きます

範囲を学習する