チェリー本 4章 その4

範囲オブジェクト

rubyには 1~5まで数値、文字a~eまでのように
範囲を示すオブジェクトが存在する。

範囲オブジェクトは..か...を使って作成する。

最初の値..最後の値(最後の値を含む)
最初の値...最後の値(最後の値を含まない)

範囲オブジェクトは変数に入れず直接include?を呼び出す時は()を使う必要がある。

#記載方法

1..5
1...5
"a".."e"

p ("a"..."e").class
=> Range

..と...の違いはinclude?を使えばわかりやすい

#最初の値..最後の値(最後の値を含む)
p (1..5).include?(3)
p (1..5).include?(5)

#最初の値...最後の値(最後の値を含まない)
p (1..5).include?(3)
p (1...5).include?(5)

範囲オブジェクトの便利な場面

配列に対して添字の代わりに範囲オブジェクトを渡すと
指定した範囲の要素を取得することができる。

a = ["a", "b", "c", "d", "e"]

#2番目、4番目の要素を取得できる。
p a[1..3]
=>
["b", "c", "d"]

シンプルに記載したい時

n以上m以下、n以上m未満の判定をしたい場合>や<とか=>を使うより
範囲オブジェクトを使用した方がシンプルに記載できる。

def liquid?(x)
  0 <= x && x < 100
end
p liquid?(-1)
p liquid?(0)
p liquid?(99)
p liquid?(100)
=>
false
true
true
false


#範囲オブジェクトの場合
def liquid?(y)
  (0...100).include?(y) #シンプルに記載できる
end
p liquid?(-1)
p liquid?(0)
p liquid?(99)
p liquid?(100)
=>
false
true
true
false

case文と組み合わせて使うこともできる

def charge(x)
  case x
  when 1..4
    0
  when 6..12
    300
  when 13..18
    600
  else
    1000
  end
end
p charge(1)
p charge(6)
p charge(13)
p charge(20)

値が連続する配列を作成する時

範囲オブジェクトに対してto_aを呼び出すと値が連続する配列を作成することができる。

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

p ("a".."d").to_a
p ("a"..."d").to_a
=>
["a", "b", "c", "d"]
["a", "b", "c"]

#[]のなかに*を記載しても
同じように配列は作れる。

p [*1..6]
=>
[1, 2, 3, 4, 5, 6]

繰り返し処理を行える。

範囲オブジェクトを配列に変換すれば配列として繰り返し処理を行うことができる。

number = (1..10).to_a
p number.inject(0) { |x, y| x += y }

=>55

#配列に変換せずに範囲オブジェクトに対して直接injectメソッドを記載しることも可能
p (1..10).inject(0) { |x, y| x += y }

stepメソッド
値を増やすと間隔を指定できる。

numbers = []

#1..10まで2つ飛ばしで繰り返し処理ができる。
(1..10).step(2) { |n| numbers << n }
p numbers