すでにメンバーの場合は

無料会員登録

GitHubアカウントで登録 Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

登録がまだの方はこちらから

Pikawakaにログイン

GitHubアカウントでログイン Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

Ruby

【Ruby】 timesメソッドで指定した回数の処理を繰り返す方法とは?

ぴっかちゃん
ぴっかちゃん

timesメソッドとは、指定した整数(オブジェクト)の回数だけ処理を繰り返すメソッドです。一定の回数だけ処理を繰り返したい場合に使われます。

timesメソッドは、整数(Integer)クラスのメソッドです。指定した整数オブジェクトの回数だけdo~end内に記述する処理が繰り返し実行されます。

timesメソッドの文法
1
2
3
整数オブジェクト.times do
  # 繰り返す処理
end

例えば次のコードでは、整数オブジェクトに5を指定しているので処理が5回繰り返し実行されます。

sample.rb | timesメソッドのサンプルコード
1
2
3
4
5
6
7
8
9
10
11
5.times do
   puts "こんにちわ、ぴっかちゃん!"
end

# 上記の実行結果
こんにちわ、ぴっかちゃん!
こんにちわ、ぴっかちゃん!
こんにちわ、ぴっかちゃん!
こんにちわ、ぴっかちゃん!
こんにちわ、ぴっかちゃん!
=> 5

この記事では、timesメソッドの基本的な使い方や他の繰り返しメソッドとの違いについて整理して学ぶことができます。

timesメソッドの使い方

この章では、timesメソッドの基本構文、処理の流れや注意点など学ぶことができます。

基本構文

timesメソッドは、整数オブジェクトの後にドット(.)を繋げて使用します。

timesメソッドの文法
1
2
3
整数オブジェクト.times do
  # 繰り返す処理
end
  • 整数オブジェクト - 正の整数を指定します。
  • do ~ end内 - 繰り返したい処理を記述します。
  • 返り値 - 指定した整数オブジェクトを返します。

処理が複数行になる場合は上記のdo~endを使いますが、処理が1行で収まる場合は以下のように{}を使って記述することができます。

処理が1行で収まる場合の書き方
1
整数オブジェクト.times {  繰り返す処理 }
sample.rb | timesメソッドのサンプルコード
1
2
3
4
5
6
5.times do
   puts "こんにちわ、ぴっかちゃん!" # 処理が1行なので{}で記述できる
end

# 上記は以下のように記述できる
5.times { puts "こんにちわ、ぴっかちゃん!" }

ブロックパラメータの指定方法

timesメソッドでブロックパラメータ(||の間に囲まれた変数)を指定する場合は、次のように記述します。

ブロックパラメータを指定する場合
1
2
3
4
5
6
数値オブジェクト.times do |変数|
  # 繰り返す処理
end

# 処理が1行で収まる場合は、以下でもよい
数値オブジェクト.times { |変数|  処理 }

ブロックパラメータには、「0」から「指定した整数-1」までの値が順番に渡されます。

例えば、次のコードのように5を指定した場合は0から4までの値が順番にブロックパラメータ(i)へ渡されます。

irb | ブロックパラメータのサンプルコード
1
2
3
4
5
6
irb(main):001:0> 5.times { |i| puts  i }
0
1
2
3
4

また、式展開を使うと次のコードのように文字列に変数を出力することもできます。

irb | 式展開も使用した場合
1
2
3
4
5
6
irb(main):002:0> 5.times { |i| puts "#{i}: こんにちわ、ぴっかちゃん!" }
0: こんにちわ、ぴっかちゃん!
1: こんにちわ、ぴっかちゃん!
2: こんにちわ、ぴっかちゃん!
3: こんにちわ、ぴっかちゃん!
4: こんにちわ、ぴっかちゃん!

実行回数とブロックパラメータに渡される値を整理すると、次の画像のようになります。

ブロックパラメータを使った場合の処理の流れ

このようにブロックパラメータを使うことで、処理が何回繰り返されているのかを知ることができます。

ポイント
  1. ブロックパラメータとは、||の間に指定された変数のことです。
  2. timesメソッドのブロックパラメータには、0から指定した整数-1までの値が順番に渡されます。

マジックナンバーの使用を避ける

通常は、本人にしか意味が分からない数値をソースコードなどに直に記述すること(マジックナンバー)は避けられています。

例えば、次のコードの5は「繰り返す回数の最小値」と本人が分かっていたとしてもコードを読む他の人には5以外の情報はなく、何を意味している数値なのか分かりませんね。

timesメソッドのサンプルコード
1
5.times { |i| puts "#{i}: こんにちわ、ぴっかちゃん!" }

マジックナンバーの本人と他人との認識の違い

このような場合は次のコードのように定数に代入することで、5に対して「繰り返す回数の最小値」という意味をつけることができます。

定数を使用する場合
1
2
MIN_TIMES = 5
MIN_TIMES.times { |i| puts "#{i}: こんにちわ、ぴっかちゃん!" }

また、マジックナンバーを避けることは数値の意味を他の人に伝えるだけではく、数値を変える場合にも定数の値を1箇所だけ書き換えるだけで済みます。

ポイント
  1. ソースコードに埋め込まれる本人しか分からない数値のことを「マジックナンバー」と呼びます。
  2. 保守性や可読性を上げるためにも定数などを利用しましょう。

timesメソッドの注意点

timesメソッドは、正の整数オブジェクトしか使用することができません。
正の整数オブジェクトを指定した場合は、次のコードのように処理が繰り返されます。

irb | timesメソッドのサンプルコード
1
2
3
4
5
6
7
irb(main):001:0> 5.times { puts "こんにちわ!" } # 5回処理が繰り返される
こんにちわ!
こんにちわ!
こんにちわ!
こんにちわ!
こんにちわ!
=> 5

しかし、正の整数オブジェクト以外を指定した場合は次のような挙動になります。

irb | timesメソッドに正の整数オブジェクト以外を指定した場合
1
2
3
4
5
6
irb(main):002:0> 0.times { puts "こんにちわ!" } # 何も表示されない
=> 0
irb(main):003:0> -5.times { puts "こんにちわ!" } # 何も表示されない
=> -5
irb(main):004:0> 5.5.times { puts "こんにちわ!" } # エラーが発生する
NoMethodError (undefined method `times' for 5.5:Float)

0-5を指定した場合は何も表示されません。5.5は、小数点がある浮動小数点数(Float)のオブジェクトなのでエラーが発生します。

timesメソッドは正の整数オブジェクトに使用するように注意しましょう。

Rubyの繰り返し

この章では、timesメソッドと同じIntgerクラスのuptoメソッドやdowntoメソッド、他のクラスの繰り返しメソッド、制御構造の繰り返しを紹介します。

uptoメソッド

uptoメソッドは、整数オブジェクトからmaxまで1ずつ増やして処理を繰り返します。

uptoメソッドの文法
1
2
3
4
5
6
整数オブジェクト.upto(max) do |変数|
  # 繰り返す処理
end

# 処理が1行の場合は、次のように記述できる
整数オブジェクト.upto(max) { |変数| 処理 }
  • 整数オブジェクト - 初期値の整数を指定します。
  • max - 最大値の整数を指定します。

ブロックパラメータ(変数)には、次のコードのように「4(整数オブジェクト)から8(max)までの値」が順番に渡されます。

irb | uptoメソッドのサンプルコード
1
2
3
4
5
6
irb(main):001:0> 4.upto(8) { |i| puts i } 
4
5
6
7
8

uptoメソッドの処理の流れ

繰り返しは、i8(max)が渡されてブロック内の処理を実行した段階で終了します。

ポイント

timesメソッドは0から指定した回数まで1ずつ増やしてループしてましたが、uptoメソッドは指定した初期値からmaxまで1ずつ増やしてループします。

downtoメソッド

downtoメソッドは、整数オブジェクトからminまで1ずつ減らして処理を繰り返すことができます。

downtoメソッドの文法
1
2
3
4
5
6
整数オブジェクト.downto(min) do |変数|
  # 繰り返す処理
end

# 処理が1行の場合は、次のように記述できる
整数オブジェクト.downto(min) { |変数| 処理 }
  • 整数オブジェクト - 初期値の整数を指定します。
  • min - 最小値の整数を指定します。

ブロックパラメータ(変数)には、次のコードのように「10(整数オブジェクト)から5(min)までの値」が順番に渡されます。

irb | downtoメソッドのサンプルコード
1
2
3
4
5
6
7
irb(main):001:0> 10.downto(5) { |i| puts i }
10
9
8
7
6
5

downtoメソッドの処理の流れ

繰り返しは、i5(min)が渡されてブロック内の処理を実行した段階で終了します。

ポイント

timesメソッドは0から指定した回数まで1ずつ増やしてループしてましたが、downtoメソッドは指定した初期値からminまで1ずつ減らしてループします。

その他の繰り返しメソッド

timesメソッドは整数(Integer)クラスのメソッドでしたが、配列ハッシュを扱う場合は、eachメソッドmapメソッドなど便利なメソッドがあります。

例えば、次のコードのようにnumbersの各要素に対して、2を足した新たな配列(new_numbers)を作りたい場合は、eachメソッドでループさせます。

irb | eachメソッドを使用した場合のサンプルコード
1
2
3
4
5
6
7
8
irb(main):001:0> numbers = [1, 2, 3]
=> [1, 2, 3]
irb(main):002:0> new_numbers = [] # 空配列を用意する
=> []
irb(main):003:0> numbers.each { |n| new_numbers << n + 2 }
=> [1, 2, 3]
irb(main):004:0> new_numbers # 各要素に2を足した配列が作成される
=> [3, 4, 5]

さらにループ処理した結果として新しい配列を返すmapメソッドを使用すると、次のように記述することができます。

irb | mapメソッドを使用した場合のサンプルコード
1
2
3
4
5
6
irb(main):005:0> numbers = [1, 2, 3]
=> [1, 2, 3] # mapメソッドは新しい配列を返すので空配列は用意しない
irb(main):006:0> new_numbers = numbers.map { |n| n + 2 }
=> [3, 4, 5]
irb(main):007:0> new_numbers
=> [3, 4, 5]

eachメソッドと違い空配列を用意する必要がないので簡潔に記述することができますね。

ポイント
  1. eachメソッドは、各要素に対してブロックの処理を実行するメソッドです。詳細は、eachメソッドの使い方を参考にしてください。
  2. mapメソッドは、各要素に対してブロックの処理を実行し、結果を新しい配列で返すメソッドです。詳細は、mapメソッドの使い方を参考にしてください。

制御構造の繰り返し

Rubyの制御構造の繰り返しは、以下の表の通りです。

繰り返し構文 説明 リンク
while 条件式がtrueの時に繰り返される whileの使い方
until 条件式がfalseの時に繰り返される untilの使い方
for オブジェクトの要素分繰り返される forの使い方
break ループを脱出する breakの使い方
next ループの処理をスキップする nextの使い方
redo ループの処理をやり直す 公式ドキュメント

この記事のまとめ

  • timesメソッドは、Integerクラスのメソッドで整数オブジェクトに使うことができる
  • 指定した回数だけ処理を繰り返すことができる
  • ブロックパラメータを利用して処理が何回繰り返されているのか知ることができる