Ruby TIPS
for文 ― ちょっと便利な繰り返し処理の構文とは?(2)
Rubyに用意されている繰り返し処理の構文のうち、for文の基本的な使い方と配列と組み合わせた利用例を解説。範囲や配列を利用して一定の回数だけ繰り返して文を実行する方法や、配列全体を処理する方法を紹介する。
前回の「TIPS:while修飾子/until修飾子/while文/until文 ― ちょっと便利な繰り返し処理の構文とは?」で紹介したように、Rubyではwhile
文/until
文/while
修飾子/until
修飾子を使った繰り返し処理が記述できる。この他に、for
文も使用できる。今回は、そのfor
文の基本的な使い方を説明し、for
文と相性のよい配列処理について見ていく。
for文の基本的な使い方
for
文は、範囲や配列やブロック
などに含まれる各オブジェクト要素を順に変数
に代入し、式
を繰り返して実行する。代入する要素がなくなったら繰り返しを終了する。
【構文】for文を使った繰り返し処理
for 変数…… in範囲や配列やブロック [do]
式……
end
範囲に対するfor文
簡単な例で見てみよう。
for i in 0..4
puts i * 2
end
|
in
の後に書かれた0..4
は0以上4以下の範囲を表す。したがって、変数i
に0、1、2、3、4が順に代入され、式が順に繰り返し実行される。
実行例は以下の通り。前回のリスト1.3と同様、10未満の偶数を表示する。
$ ruby sample008.rb
0
2
4
6
8
$
|
プログラムを実行すると、変数i
の値が表示される。動作を確認するためだけなので、何の変哲もない結果だが、変数i
の値が10未満である間は繰り返されていることがわかる。
範囲を表すオブジェクトはa..b
のように..
で区切ると「a以上b以下」という意味になり、a...b
のように...
で区切ると「a以上b未満」という意味になる。for
文は前判断型なので、in
の後にオブジェクトが1つもない場合には繰り返し処理の中身は実行されない。
配列に対するfor文
また、in
の後には、配列も指定できるので、リスト2.1の例は以下のようにも書ける。
for i in [0,1,2,3,4]
puts i * 2
end
|
in
の後に書かれた配列の要素が変数i
に順に代入され、式が順に繰り返し実行される。
ブロックを利用した繰り返し処理
繰り返し処理を行うには、for文を使う方法以外にも、ブロックを利用する方法もある。例えば、リスト2.3やリスト2.4のように書いても上で見た例と同じことができる。ブロックについての詳細は、次回以降のTIPSで説明するので、今回はコードを掲載するにとどめたい。
5.times do |i|
puts i * 2
end
|
Integer
クラスのtimes
メソッドを使えば、ブロックパラメーター(=|
~|
で囲まれた中にある変数)に0からtimes-1までの整数が順に渡される。つまりi
には0から4までが順に渡されることになる。
a = [0, 1, 2, 3, 4]
a.each do |i|
puts i * 2
end
|
Array
クラスのeach
メソッドを使えば、ブロックパラメーター(=|
~|
で囲まれた中にある変数)に配列の各要素が順に渡される。つまりi
には0から4までが順に渡されることになる。
これらについても、実行例は前掲の実行例2.1と同じなので省略する。
for文と配列
for
文による繰り返し処理は、範囲を使って変数の値を順に変えていくことができるので、配列の処理ととても相性がいい(配列の基本については「TIPS:関数で複数の返り値を返す/関数の引数は値渡し ― コーディングミスを防ぐには?(2)」を参照してもらいたい)。
配列
例えば、すごろくのようなゲームで、マス目を配列で表すものとする。特に何もないマスには0という値を入れ、1つ進むマスに1を入れておくのであれば、以下のようなコードを書けばよい。
limit = 10 # マス目は10個
cells = Array.new(limit)
# すべて0にする
for i in 0..limit-1
cells[i] = 0
end
# セルをランダムに選んで1を入れる
r = Random.new()
cells[r.rand(10)] = 1
# 配列の内容を表示してみる
p cells
|
配列cells
の要素数はlimit
で表されており、ここでは10を指定している。for
文では、0からlimit-1までをi
に代入しながら処理を繰り返す。実行する処理は単に配列のi
番目の要素に0を代入するだけ。続いてランダムに選択したセルに1を入れる。
実は、全ての要素を0にするには、繰り返し処理を使わなくてもcells.fill(0)
だけでも構わない。ここでは、繰り返し処理の書き方を知るためにあえてfor
文を使った。実行結果は以下のようになる。1が表示される位置はランダムに決まる。
$ ruby sample012.rb
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
|
p
メソッドを使って配列の要素を全て表示してみた。繰り返し処理によって全ての要素に0を代入した後、ランダムな位置の要素に1を代入したことが分かる。
二次元配列
2次元の配列の要素を全て処理したい場合には、for
文を二重にネストすればよい(=入れ子にする)。以下の例は単に2次元の配列を作り、その要素に「n行n列」という文字列を代入するだけのプログラムである。
# 2次元の配列を作る
def make2d(x,y)
a = Array.new(x)
for i in 0..x-1
a[i] = Array.new(y)
end
return a
end
# 2次元の配列の全ての要素に値を代入する
a = make2d(3, 4)
for row in 0..2
for col in 0..3
a[row][col] = row.to_s + "行" + col.to_s + "列";
end
end
# 配列の対角要素の値だけを表示する
for i,j in [[0,0],[1,1],[2,2]]
puts a[i][j]
end
|
最初に2次元の配列を作るためのmake2d
関数を定義してある。その関数を使って2次元の配列を作成し、変数a
でその配列を参照できるようにする。続いて、for
文を二重にして配列a
の各要素に値を代入する。最後に、配列の対角要素だけを表示している。
このプログラムのポイントは2つ。
まず、2次元の配列を二重のfor
文で処理するところだが、row
は0から2まで、col
は0から3まで以下の図のように変化する。内側のfor
文に描かれている変数col
が先に動くことに注意しよう。
col
が内側のfor
文で使われる変数で、row
が外側のfor
文で使われる変数。
もう1つのポイントは、最後のfor
文。このように、複数の変数に一度に値を代入しながら繰り返しができる。最初に、i,j
に[0,0]
がそれぞれ代入され、puts
が実行される。次に[1,1]
がそれぞれ代入されてputs
が実行され、最後に[2,2]
がそれぞれ代入されてputs
が実行される。for
文のネストとは異なるが、複数の変数の値を簡潔な書き方でまとめて変えられる便利な機能だ。最後に実行例を示しておこう。
$ ruby sample013.rb
0行0列
1行1列
2行2列
|
作成した配列は正方行列ではないが、行番号と列番号が同じ要素を表示してみた。for
文をネストさせた場合や、複数の変数に値を代入しながら繰り返し処理を実行させた場合の結果が確認できる。
まとめ
Rubyでは、while
文/until
文/while
修飾子/until
修飾子を使った繰り返し処理ができるほか、各種プログラミング言語でも一般的なfor
文を使った記述方法もサポートされている。そのfor
文では、範囲や配列などのオブジェクトの要素を順に変数に代入しながら繰り返し処理が書ける。
※以下では、本稿の前後を合わせて5回分(第8回~第12回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
8. if修飾子/unless文/case文 ― ちょっと便利な条件分岐の構文とは?
Rubyには、if文のような一般的なもの以外にも、if修飾子/unless文/unless修飾子/case文といった便利な条件分岐の構文が用意されている。その基本的な使い方を解説。
9. while修飾子/until修飾子/while文/until文 ― ちょっと便利な繰り返し処理の構文とは?(1)
Rubyに用意されている繰り返し処理構文のうち、while文/until文の基本的な使い方と落とし穴を解説。また、while/until「修飾子」を使った簡潔な記述方法にも言及する。
10. 【現在、表示中】≫ for文 ― ちょっと便利な繰り返し処理の構文とは?(2)
Rubyに用意されている繰り返し処理の構文のうち、for文の基本的な使い方と配列と組み合わせた利用例を解説。範囲や配列を利用して一定の回数だけ繰り返して文を実行する方法や、配列全体を処理する方法を紹介する。
11. ブロック ― ちょっと便利な繰り返し処理の構文とは?(3)
Rubyに用意されている繰り返し処理の構文のうち「ブロック」を使えば、繰り返し処理をより簡潔に書ける。その基本的な使い方と、自作メソッドでの利用例を解説する。
12. クラスとそのコンストラクター/アクセサー/メソッドを定義し利用するには?
Rubyプログラミングの基本中の基本として、クラスの定義から、そのインスタンスの作成・利用、インスタンスメソッドの定義、変数へのアクセスまでを説明する。