みなさんこんにちは!
今回は、
-206x300.png)
・どの場面でどれを使えばいいか分からない…
・途中で繰り返しを中断する方法も知りたい
というお悩みを解決する記事になっています。
繰り返し処理は、プログラミングにおいて最も基本的ともいえる要素です。
しかし、一口に繰り返し処理と言っても実装方法はさまざま存在するため、どのやり方を採用するのが最適なのかを考えることは、プログラミングスキルを身につけるうえで大事なポイントです。
今回は、Rubyで繰り返し処理を実装する際に使用する構文やメソッドを詳しく解説していきます。
どういった場合にどの処理を使用すればよいかが分かるよう、サンプルコードを交えて説明しますので、ぜひ最後まで読んでみてください。
なお、Rubyの魅力や特徴については以下の記事で詳しく解説していますので、こちらもぜひご覧くださいね。
みなさんこんにちは! 今回の記事は、 悩みを抱えた人 ・Rubyってどんなプログラミング言語なの?・Rubyを勉強すると将来役に立つかな?・Rubyのおすすめの学習方法が知りたい! というお悩みを解決する記事にな[…]
フリーランス案件を探すならこのエージェント!
転職を考えているならこのエージェント!
繰り返し処理の基本構文
Rubyでは、繰り返し処理を実装する際に利用できるキーワードが複数存在します。各々の特徴と実装方法について、詳しく解説していきます。
while
1つ目は、「while」です。whileによって実装された繰り返し処理は、与えられた条件式がfalseになるまで処理を繰り返します。以下のサンプルコードで、whileによる繰り返し処理の実装方法を確認しましょう。
MAX_SIZE = 100 # 生成するデータの個数
random_data = [] # 生成するデータを格納する配列
count = 0 # 繰り返し処理用カウンタ
# whileキーワードによる繰り返し処理の基本形
# while [条件式] do
# 繰り返し処理
# end
while count < MAX_SIZE do
random_data.push(rand(1000..10000))
count += 1
end
p random_data
乱数を生成するrand()メソッドを利用してランダムに数値を生成し、配列に順番に格納するプログラムです。
rand()メソッドについては以下の記事にて詳しく詳しく解説していますので、使い方を忘れた方はこちらもぜひご覧くださいね。
Rubyに限らず、あらゆるプログラミング言語では、ランダムに数値を生成する「乱数生成機能」が用意されています。その中でも、Rubyには乱数を生成する方法がいくつか存在し、それぞれどのような違いあるのかを理解することが重要です。 今回[…]
今回は、生成するデータのサイズを100に設定し、whileを利用して100回生成処理を繰り返すように実装しています。
whileによる繰り返し処理の終了条件は、9行目にある「count < MAX_SIZE」です。処理を繰り返す中で変数countはインクリメントされ、いずれ条件式が成り立たなくなります。
whileで繰り返し処理を実装する場合は、処理を終了する条件式が明確に定義できるケースで適用しましょう。ただし、配列やハッシュなどの列挙形式のデータを取り扱う場合は、後に解説するforを利用するのがおすすめです。
until
2つ目に紹介するキーワードは、「until」です。
繰り返し処理の終了条件を条件式で記述するなど、構造的にはwhileと似ていますが、untilは条件式がtrueになるまで繰り返し処理が続行され、whileと逆になっているので注意してください。
それでは、以下のサンプルコードで確認しましょう。
divisor_array = [] # 約数を格納する配列
p "約数の判定を行います。"
p "数字を入力してください"
source_number = 0
# untilキーワードによる繰り返し処理の基本形
# until [条件式] do
# 繰り返し処理
# end
# 1以上の数字が入力されるまで繰り返し
until source_number != 0
# 数値入力を受付
source_number = gets.to_i
end
divisor_number = 1 # 約数を判定するための変数
# 割る数が入力値に達するまで繰り返し
until divisor_number > source_number
if source_number % divisor_number == 0
divisor_array.push(divisor_number)
end
divisor_number += 1
end
p source_number.to_s + "の約数は以下の通り"
p divisor_array
入力された数字に対して約数を求め、配列に格納した後コンソール上に約数を出力するプログラムです。
untilは、数値入力を受け付ける処理と、約数を判定する処理の二箇所において用いています。untilはwhileと違い、条件式がfalseである間は繰り返し処理を続行します。
for
3つ目は、「for」です。forは、配列や範囲オブジェクトなどの列挙データから、要素を1つずつ抽出しながら処理を行いたいときに利用します。
以下のサンプルコードで実装方法を確認しましょう。
stock_product = [
['製品A', 60],
['製品B', 54],
['製品C', 65],
['製品D', 55],
['製品E', 75],
['製品F', 66],
['製品G', 61]
]
PRODUCT_NAME = 0
PRODUCT_COUNT = 1
# forキーワードによる繰り返し処理の基本形
# for [各要素を格納する変数] in [配列・ハッシュなど] do
# 繰り返し処理
# end
for product in stock_product do
if product[PRODUCT_COUNT] < 60
p "#{product[PRODUCT_NAME]}:#{product[PRODUCT_COUNT]}個(在庫がなくなりかけています)"
else
p "#{product[PRODUCT_NAME]}:#{product[PRODUCT_COUNT]}個"
end
end
製品名と個数を1つの要素とした二次元配列に対して、1つずつその情報をコンソール上に出力、加えて個数が60個未満であれば、在庫が少なくなっている旨を併せて出力するプログラムです。
forは、列挙データの中から1つずつ取り出して処理を実行し、全て取り終えたら自動的に繰り返し処理を終了します。したがってwhileと違い、繰り返しを終わらせるための条件式を定義する必要はありません。
繰り返し処理の応用的な制御
while・until・forさえあれば、簡単な繰り返し処理は難なく実装できます。
しかし、繰り返し処理を実装していくうちに、特定の条件の場合は処理を中断したりスキップしたりしたいケースも往々にして出てきます。
ここでは、より応用的な繰り返し処理を実装する方法を、ケース別に解説していきましょう。
繰り返し処理を中断する
ある特定の条件を満たした場合に、繰り返し処理を途中で終わらせたいケースでは、breakキーワードを利用しましょう。サンプルコードは、以下の通りです。
# 乱数で生成した値が3桁のゾロ目に
# なるまでの試行回数をカウントするプログラム
count_1 = 0
while true
num_1 = rand(0..9)
num_2 = rand(0..9)
num_3 = rand(0..9)
count_1 += 1
if num_1 == num_2 && num_2 == num_3
# ゾロ目になったら繰り返し処理を中断
break
end
end
p "ゾロ目試行回数:#{count_1}回(#{num_1}#{num_2}#{num_3})"
# 乱数で生成した値が左から連番に
# なるまでの試行回数をカウントするプログラム
count_2 = 0
until false
num_4 = rand(0..9)
num_5 = rand(0..9)
num_6 = rand(0..9)
count_2 += 1
if num_4 == num_5-1 && num_4 == num_6-2
# 連番になったら繰り返し処理を中断
break
end
end
p "連番試行回数:#{count_2}回(#{num_4}#{num_5}#{num_6})"
# 用意された配列の中にnilが
# 含まれているかを判定するプログラム
sample_data = [12, 54, 56, 34, 643, nil, 23, 6, 4, 2, 22]
for data in sample_data
if data == nil
# nilが含まれていたら繰り返し処理を中断
p "nilが含まれているので処理を中断します"
break
end
end
繰り返し処理を中断するために条件式を記述する必要があることから、breakキーワードは、ifと併せて利用することが多いです。
whileを利用したプログラムでは、各変数が全て等しくなったときを繰り返し処理中断の条件としています(11行目)。
同様に、untiilを利用したプログラムは、各変数が連番であること(30行目)、forを利用したプログラムは、配列の要素にnilが含まれていること(43行目)を条件式として実装しています。
繰り返し処理をスキップする
ある条件を満たすときに、繰り返し処理を切り上げて次のループに処理を移したいケースでは、nextキーワードを利用しましょう。
サンプルコードは以下の通りです。
sample_sentence = [
"This is a pen.",
"I'm Ruby programmer",
"",
"Programming is fun.",
"",
"Have a nice day!"
]
for str in sample_sentence
if str == ""
# 空文字の場合はスキップ
next
end
p str
end
基本的な使い方はbreakのときと同様に、スキップする条件式をifを使い併せて記述すれば良いです。
今回のサンプルコードでは、空文字であることを条件としています。これにより、空文字がコンソール上に出力されることはありません。
繰り返し処理をやり直す
繰り返し処理をスキップさせるのではなく、再度処理をやり直したいケースは、redoキーワードを利用しましょう。
サンプルコードは、以下の通りです。
sample_sentence = [
"This is a pen.",
"I'm Ruby programmer",
"",
"Programming is fun.",
"",
"Have a nice day!"
]
index = 0
for str in sample_sentence
if str == ""
# 空文字の場合は新たに文字列を入れ直す
str = "--------------------"
redo
end
index += 1
p str
end
redoについてもbreakやnextと同様に、ifと併せて記述することが多いです。redoは「やり直す」という意味を持ち、操作を再実行するという意味合いで利用するのが最適であると言えます。
繰り返し処理を1行で記述する
while・untilを利用して繰り返し処理を実装する場合、以下のサンプルコードのように繰り返し処理自体を1行で記述することも可能です。
input_char = ""
# 10文字以上の文字列(改行を含まない)が入力されるまで
# 入力を受け付ける
input_char = gets while input_char.chomp.size < 10
p "10文字以上入力されました(#{input_char})"
input_char = ""
# 10文字以上の文字列(改行を含まない)が入力されるまで
# 入力を受け付ける
input_char = gets until input_char.chomp.size >= 10
p "10文字以上入力されました(#{input_char.chomp})"
繰り返し処理を1行で記述できる場合は、繰り返し処理を先に置いてからwhileまたはuntilを置き、その後に条件式を記述します。
通常通り記述するよりもソースコードの見た目が簡潔で、可読性の向上に一役買っています。
繰り返し処理を最低一回実行する
今まで紹介した繰り返し処理は、処理を始めるより前の段階で、繰り返し処理を開始するか否かを判断しています。
一方、最低一回は処理を実行してその後に繰り返し処理を続行するかを判断したい場合は、beginキーワードを併せて利用しましょう。
サンプルコードは以下の通りです。
PASS_SIZE = 8
# 入力受付処理(while)
begin
p "パスワードを入力してください"
input_str = gets.chomp
end while input_str.size < PASS_SIZE
p "入力したパスワード:#{input_str}"
# 入力受付処理(until)
begin
p "パスワードを入力してください"
input_str = gets.chomp
end until input_str.size >= PASS_SIZE
p "入力したパスワード:#{input_str}"
while・endではなく、begin・endで繰り返したい処理を囲むことで、最低一回は繰り返し処理が実行されるようになります。
繰り返し処理の続行判定は、endキーワードの後にwhile・untilと条件式を記述することで実施できます。
繰り返し処理を実装する便利なメソッド
Rubyでは、ここまでご紹介した実装方法以外にも繰り返し処理を実行するメソッドが多数用意されており、それらを利用することで、繰り返し処理をより簡潔に実装でき、ソースコードの可読性を向上させることができます。
今回は、以下の3つのメソッドについて簡単な使い方を解説しましょう。
- each()メソッド
- times()メソッド
- loop()メソッド
each()メソッド
1つ目は、each()メソッドです。
each()メソッドは、配列やハッシュといった形式のデータをレシーバとして呼び出し、繰り返したい処理をブロックで定義して渡します。
サンプルコードは以下の通りです。
random_str = ['Ruby', 'PHP', 'JavaScript', 'C', 'Python', 'Java']
# each()メソッドの基本形
# [レシーバ(配列・ハッシュなど)].each { |ブロック引数| 繰り返したい処理 }
random_str.each { |str| p str }
文字列が格納された配列の中身を、1要素ずつコンソール上に出力するプログラムです。ブロックで定義されている引数strには、配列の各要素が格納され順番に実行されます。
times()メソッド
2つ目は、times()メソッドです。
数値データをレシーバとして呼び出すメソッドで、each()メソッドと同じく繰り返したい処理を定義したブロックを渡すことで実行できます。
サンプルコードは以下の通りです。
# times()メソッドの基本形
# [レシーバ(数値データ)].each { |ブロック引数| 繰り返したい処理 }
100.times { |num| p num }
構造的にはeach()メソッドと大差ないことが見て取れます。
一方で、times()メソッドによる繰り返し処理の実行回数はレシーバの値となります。つまり、上記サンプルコードの実行回数は100回です。
loop()メソッド
3つ目は、loop()メソッドです。
レシーバを必要とせず、繰り返し処理が中断するような条件が記載されていない限り、ブロック内の処理を無限に繰り返し続けます。
サンプルコードは以下の通りです。
count = 0
loop {
p "I'm Ruby Programmer."
break if count > 100 # loop()メソッドを中断する条件
count += 1
}
loop()メソッドも他のメソッド同様、繰り返したい処理を定義したブロックを渡します。
ただし、他のメソッドと違ってレシーバが存在しないため、繰り返し処理を終える条件はブロック内に定義しておく必要があります。
もし定義しなかった場合、永遠にプログラムが終了しないため注意してください。
お仕事の途中ですが、少し一休みして、転職や独立について考えてみませんか🙌?
現役エンジニアが選ぶおすすめの転職エージェント11選【成功談・失敗談もあります】
レバテックフリーランスの評判ってどう?【現役エンジニアが徹底解説します】
MidWorks(ミッドワークス)の評判ってどう?【現役エンジニアが徹底解説します】
日々の業務に追われて自分を見失わないよう、
定期的にキャリアを振り返るようにしておきましょう🤲
最後に
今回は、Rubyで繰り返し処理を実装する際に覚えておくべき構文・メソッドを6つご紹介させていただきました。
繰り返し処理は、それを使わないプログラムはないと言っても良いほど基本的な処理になりますので、ぜひこの機会にマスターしておきましょう。
最後にもう一度、本記事の内容を確認しておきましょう。
- 繰り返し処理を実装する基本構文
→while、until、forの3つの構文をご紹介しました - 繰り返し処理を中断する/スキップする/やり直す方法
→break、next、redoなどをご紹介しました - 繰り返し処理を実装する際に便利なメソッド
→each()メソッド、times()メソッド、loop()メソッドをご紹介しました
このブログを通じて少しでも「傍(はた)を楽(らく)にする」ことができていれば嬉しく思います。
最後まで読んで頂きありがとうございました。