RubyのRange(範囲)をマスター!数値・文字・日付の操作と便利なメソッド解説
生徒
「Rubyで範囲を表すRange(レンジ)を勉強中なのですが、数字以外にも使えるって本当ですか?」
先生
「その通りです!Rangeは数値だけでなく、文字や日付の範囲を扱うのにも非常に優れているんですよ。」
生徒
「日付まで!でも、中身が含まれているか確認する方法がいくつかあって、どれを使えばいいか迷っちゃいます…。」
先生
「stepやcover?、include?といったメソッドの違いですね。初心者の方が設計で迷わないように、使い分けを丁寧に解説します!」
1. Range(範囲オブジェクト)で扱えるデータ型
RubyのRange(範囲オブジェクト)は、データの「始まり」と「終わり」を決めて、その間のまとまりを扱うための仕組みです。プログラミング未経験の方は、まず「数字の1から10まで」を想像するかもしれませんが、実はRubyではそれ以外にも多くのデータを範囲として定義できます。
具体的には、以下の3つのパターンがよく使われます。
- 数値:
1..100(1から100まで) - 文字:
"a".."z"(aからzまで) - 日付:
Date.new(2026, 1, 1)..Date.new(2026, 1, 31)(1月の1ヶ月間)
このように、順番が決まっているデータであれば、何でも範囲にすることができるのがRubyの強みです。パソコンを触ったことがない方でも、カレンダーの期間指定や、名簿のあいうえお順の範囲指定をイメージすれば、この便利さが伝わるはずです。
2. stepメソッドで「飛び飛び」の値を扱う
範囲内のデータをすべて順番に扱うのではなく、「2つ飛ばしで取得したい」「5ずつ増やしたい」という時に便利なのが step メソッドです。メソッドとは、データに対して行う「命令」のようなものだと考えてください。
例えば、1から10までの範囲で、1つ飛ばし(奇数だけ)を表示させたい場合は、次のように書きます。
# 1から10までの範囲で、2ずつ進む
(1..10).step(2) do |n|
puts "#{n} です"
end
実行結果は以下の通りです。
1 です
3 です
5 です
7 です
9 です
このように、一定の「歩幅」で範囲内を移動できるのが step の特徴です。これは数値だけでなく、文字の範囲でも使えます。例えば「aからzまでを3つ飛ばしで」といった指定も可能です。
3. include? メソッド:要素が「仲間」か確認する
範囲の中に特定のデータが含まれているか調べたい時、一番よく使われるのが include? です。これは「そのデータが範囲内のリストに含まれているか?」を丁寧に一つずつチェックするようなイメージの命令です。
特に数値や文字など、順番が明確なデータに対して、その値が「範囲の一部として存在するか」を判定するのに適しています。以下のコードで、文字の範囲での使い方を見てみましょう。
# aからeまでの範囲
alphabet = "a".."e"
puts alphabet.include?("c") # 含まれるので true
puts alphabet.include?("z") # 含まれないので false
実行結果は以下の通りです。
true
false
初心者の方は、まずこの include? を覚えておけば間違いありません。質問形式で「?」がついているので、「含まれていますか?」というプログラムの意図が読みやすくなりますね。
4. cover? メソッド:範囲の「端と端」で判定する
include? と似ていて、よく混同されるのが cover? です。このメソッドの大きな違いは、判定の方法にあります。include? が「中身を一つずつ数える」イメージなのに対し、cover? は「始まりと終わりの値の間に収まっているか」だけを確認します。
この違いが特に重要になるのが、「文字」の範囲です。例えば "a".."c" という範囲に対して "ba" という文字列が含まれるか判定する場合、include? だと「a, b, cの中にbaという文字はない」ので false になりますが、cover? だと「aとcの間にあるからOK」という判定になります。
# aからcまでの範囲
range = "a".."c"
puts range.include?("ba")
puts range.cover?("ba")
実行結果は以下の通りです。
false
true
cover? は端っこの値(境界)だけを見るため、非常に動作が速いというメリットもあります。膨大な範囲をチェックするときや、順番さえ合っていれば良いときには cover? を選ぶのが賢い設計ルールです。
5. 日付のRangeを使いこなす実践例
Rubyでカレンダーのような機能を扱う際、日付のRangeは欠かせません。日付を扱うには date というライブラリ(便利な道具セット)を読み込む必要があります。require 'date' と書くことで、Rubyが日付を理解できるようになります。
例えば、「特定のプロジェクト期間内に、今日が含まれているか」を確認するプログラムを作ってみましょう。日付の範囲でも include? や cover? が使えます。
require 'date'
# 2026年1月1日から1月31日までの範囲
project_term = Date.new(2026, 1, 1)..Date.new(2026, 1, 31)
# チェックしたい日付
check_day = Date.new(2026, 1, 15)
if project_term.cover?(check_day)
puts "期間内です。作業を進めましょう!"
else
puts "期間外です。"
end
実行結果は以下の通りです。
期間内です。作業を進めましょう!
日付の場合、include? よりも cover? を使うのが一般的です。なぜなら、日付は時刻のように連続した流れを持つものなので、「範囲の間に収まっているか」という判定の方が自然だからです。
6. メモリを節約するRangeの設計メリット
プログラミングにおいて「メモリ」とは、コンピュータが作業中に一時的にデータを入れておく場所のことです。初心者のうちはあまり意識しなくて良いですが、Rangeを使うことはこのメモリの節約に大きく貢献します。
例えば「1から100万までの数字」を配列(Array)で作ると、100万個分の数字すべてをメモリに保存しようとして、パソコンが重くなってしまいます。しかし、Range(1..1000000)なら、「始まりは1、終わりは100万」という情報だけを記憶すれば良いので、メモリをほとんど使いません。
このように、大きなデータの塊を扱うときこそ、配列ではなくRange(範囲オブジェクト)を活用するのがプロの技です。to_a という命令を使って無理やり配列に変換しない限り、Rangeは非常に軽量でエコなデータ型なのです。
7. 条件分岐(case文)とRangeの相性の良さ
Rangeが最も輝く場面の一つが、以前学習した「条件分岐」での利用です。特に case 文という、複数の条件を並べる書き方で真価を発揮します。if 文よりもスッキリ書けるため、プログラムの読みやすさが格段に上がります。
テストの点数によって評価を変えるプログラムを例に見てみましょう。範囲を指定することで、「〜点から〜点まで」という条件を非常にシンプルに記述できます。
score = 85
case score
when 90..100
puts "大変優秀です!"
when 70..89
puts "合格です!"
when 0..69
puts "もう少し頑張りましょう。"
end
実行結果は以下の通りです。
合格です!
このように、case 文の when にRangeを置くと、Rubyは自動的に include?(または内部的な判定)を行ってくれます。数値を一つずつ score >= 70 && score <= 89 と書くよりも、ずっと人間にとって分かりやすい言葉になりますよね。これがRubyが「直感的」と言われる理由の一つです。
8. 逆向きの範囲を作るときの注意点
最後に、初心者がよくやってしまう間違いを紹介します。それは「大きい数から小さい数へ」の範囲を作ろうとすることです。例えば、10..1 と書いても、Rubyはこれを「空の範囲」として扱ってしまい、10からカウントダウンしてくれることはありません。
もし逆向きに値を扱いたい場合は、step メソッドにマイナスの値を指定するか、範囲を作った後に to_a.reverse(逆順にする)といった工夫が必要です。範囲オブジェクト自体は、あくまで「左(開始)から右(終了)」へ進むものだと覚えておきましょう。
# 10から1まで逆向きに作りたい場合(これは空になる)
bad_range = 10..1
puts bad_range.to_a.inspect
# 正しい逆向きの処理(逆順のリストにする)
good_way = (1..10).to_a.reverse
puts good_way.inspect
実行結果は以下の通りです。
[]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
「10から1まで」という範囲そのものを作ることはできませんが、やりたいことに合わせてメソッドを組み合わせれば解決できます。こうした小さなルールの積み重ねが、バグ(プログラムのミス)のない綺麗なコード作成に繋がります。