Rubyの範囲オブジェクトRange入門!1..10と1...10の違いを徹底解説
生徒
「Rubyで『1から10まで』みたいな数字の塊を簡単に扱う方法はありますか?」
先生
「それなら『範囲オブジェクト(Range)』を使うのが一番ですよ。点々を使って簡単に書けるんです。」
生徒
「点々ですか?さっき本で見たら、点が2つのものと3つのものがあったのですが、何が違うんですか?」
先生
「実はその点の数の違いが、最後の数字を含むか含まないかの分かれ道なんです。初心者の方が一番迷うポイントなので、詳しく説明しますね!」
1. 範囲オブジェクト(Range)とは?
Rubyの範囲オブジェクト(Range)とは、その名の通り「始まりの値」から「終わりの値」までの連続したデータの集まりを表すための特別な道具です。プログラミング未経験の方には、「出席番号1番から10番まで」といった名簿の範囲や、「1月1日から12月31日まで」といったカレンダーの期間をイメージしてもらうと分かりやすいでしょう。
Rubyでは、この範囲をたった数文字で表現することができます。わざわざ「1, 2, 3...」と全部書く必要がないため、大量の数字や文字を扱うときに非常に便利です。この便利な道具を使いこなすことで、プログラムを短く、そして読みやすく書くことができるようになります。まずは「範囲=データのまとまり」という基本をしっかり押さえておきましょう。
2. 点が2つの「..」は最後を含む(以上・以下)
まずは、ドット(点)を2つ使う書き方を学びましょう。1..10 のように書くと、これは「1から10まで」という意味になります。ここで最も重要なルールは、「最後の数字(10)も含まれる」ということです。
算数や数学の言葉で言えば、「1以上、10以下」という表現になります。日常生活で「10日まで宿題を出してください」と言われたら、10日当日も含まれますよね。それと同じ感覚で使えるのが、この点2つの書き方です。具体的なプログラムの書き方を見てみましょう。
# 1から5までの範囲を作成(5を含む)
range_five = 1..5
# 配列(データのリスト)に変換して中身を確認
puts range_five.to_a.inspect
実行結果は以下の通りです。
[1, 2, 3, 4, 5]
to_a というのは「範囲を配列(リスト形式)に変えてね」という命令で、inspect は「中身を分かりやすく表示してね」という命令です。結果を見ると、しっかり「5」まで入っていることがわかりますね。
3. 点が3つの「...」は最後を含まない(未満)
次に、ドットを3つ使う書き方 1...10 です。こちらは「1から10の直前まで」という意味になります。つまり、「最後の数字(10)は含まれない」のです。
専門的な言葉では「1以上、10未満」と言います。例えば、「10歳未満は無料です」と言われたら、10歳の人は含まれず、9歳までが対象になりますよね。プログラミングでは、この「最後の一つ手前まで」という考え方を非常によく使います。データの数(長さ)を指定するときなどに重宝するので、点2つとの違いをしっかり意識しましょう。
# 1から5までの範囲を作成(5を含まない)
range_four = 1...5
# 配列に変換して中身を確認
puts range_four.to_a.inspect
実行結果は以下の通りです。
[1, 2, 3, 4]
このように、最後が「4」で止まっています。点が一つ増えるだけで結果が変わるのがプログラミングの面白いところであり、注意が必要なところでもあります。
4. 数字だけじゃない!文字の範囲(アルファベット)
範囲オブジェクトが扱えるのは数字だけではありません。なんと、アルファベットなどの「文字」も範囲として指定することができます。例えば「aからzまで」といった指定も簡単です。
パソコンの内部では、文字にも順番(キャラクターコードと言います)が決まっているため、Rubyはその順番に従って範囲を作ってくれます。これを使えば、アルファベットのリストをわざわざ手入力する必要はありません。以下のコードで試してみましょう。
# 「a」から「e」までの文字の範囲
alphabet_range = "a".."e"
# 配列にして表示
puts alphabet_range.to_a.inspect
実行結果は以下の通りです。
["a", "b", "c", "d", "e"]
まるで魔法のように、間の文字が自動で補完されましたね。なお、日本語のひらがななども範囲にできますが、初心者の方はまずは数字とアルファベットで練習するのがおすすめです。
5. 範囲内に値が含まれているか確認する:include?
作成した範囲の中に、ある特定のデータが入っているかどうかを調べたいときがあります。その時に使うのが include?(インクルード)というメソッドです。メソッドとは、特定のデータに対して「〜して」とお願いする命令のことです。
例えば、「今日のラッキーナンバーが1から100の間に入っているか?」を判定するようなプログラムが簡単に作れます。この命令は、含まれていれば true(はい)、含まれていなければ false(いいえ)という結果を返してくれます。
# 10から20までの範囲
my_range = 10..20
# 15が含まれているか?
puts my_range.include?(15)
# 25が含まれているか?
puts my_range.include?(25)
実行結果は以下の通りです。
true
false
質問するように include? と書くので、コードを読んだときに意味が分かりやすいのがRubyの素敵な特徴です。これを if 文と組み合わせることで、「もし点数が80点から100点の間なら合格!」といった処理が作れるようになります。
6. 範囲の端っこを取得する:begin と end
範囲オブジェクトから、「始まりの値」と「終わりの値」を個別に知りたいこともあります。その場合は begin(ビギン)と end(エンド)という命令を使います。文字通り「開始」と「終了」ですね。
プログラムが複雑になってくると、変数(データの入れ物)の中にどんな範囲が入っているのかを調べ直す必要が出てきます。そんな時にこれらのメソッドが役立ちます。
# 50から100までの範囲
exam_range = 50..100
puts "開始の値: #{exam_range.begin}"
puts "終了の値: #{exam_range.end}"
実行結果は以下の通りです。
開始の値: 50
終了の値: 100
このように、範囲全体を壊さずに、端っこの情報だけを抜き出すことができます。なお、点が3つの ... を使った場合でも、end は指定した最後の数字(含まない方の数字)を返します。ここは少し勘違いしやすいので、「指定した時の右側の数字が返ってくる」と覚えておきましょう。
7. 範囲オブジェクトを繰り返し処理で使う
範囲オブジェクトの最も強力な使い道の一つが、「繰り返し処理」との組み合わせです。「10回繰り返して」と言いたいとき、1..10 を使えばとてもシンプルに書けます。Rubyでよく使われる each(イーチ)という命令とセットで使ってみましょう。
each は、範囲の中に入っているデータを一つずつ順番に取り出して、特定の処理を実行してくれる便利な機能です。パソコンに同じ作業を何度もさせたいときに、範囲オブジェクトは最高の相棒になります。
# 1から3まで順番に挨拶する
(1..3).each do |num|
puts "#{num}回目のこんにちは!"
end
実行結果は以下の通りです。
1回目のこんにちは!
2回目のこんにちは!
3回目のこんにちは!
do から end までの間に書いた命令が、範囲の数だけ繰り返し実行されます。|num| という部分には、今何番目のデータを扱っているかの数字が自動的に入ります。これで、100回でも1000回でも、一瞬で同じ処理を繰り返させることが可能になります。
8. 実践的な使い分け!どちらを使うべき?
最後に、「..」と「...」をどのように使い分けるべきか、初心者の方に向けた実践的なアドバイスをお伝えします。基本的には、日常生活と同じ感覚で使える 「..」(最後を含む)をメインに使えばOKです。直感的に理解しやすいため、間違いが少なくなります。
一方で、「...」(最後を含まない)は、ITの世界の特殊なルールに合わせる時に使います。例えば、「データが10個あるから、0番から9番まで(10の手前まで)処理したい」といった場面です。プログラミングの経験を積んでいくと、この「一つ手前まで」という考え方が非常にスマートに感じられる瞬間がやってきます。まずは「ドットが3つだと、最後は遠慮して含まないんだな」というイメージを持っておくだけで、設計で迷うことはなくなるはずです。