Rubyのeachメソッドは、配列やハッシュを使った繰り返し処理を記述する際によく使われます。とはいえ、ブロック構文の書き方をマスターしていない方にとっては、使い難いと思えるかもしれません。
今回は、eachメソッドの使い方を、ブロック構文を使った具体的な例を用いて紹介します。
Rubyのeachメソッドの基本
eachメソッドは、配列またはハッシュの要素を1つずつ取り出し、それを使った処理が記述できるメソッドです。そして、配列やハッシュは、eachメソッドとともにRubyのプログラムでよく使われます。ぜひ、使い方をマスターしましょう。
まずは、Rubyのeachメソッドの基本について、解説します。
配列を使った繰り返し処理
先ほど説明したように、eachメソッドは、配列またはハッシュの要素を1つずつ取り出し、ブロック構文にその要素を使った処理を記述できるメソッドです。
なお、Rubyに限らずプログラムでは、繰り返し処理が使われますが、配列を使った繰り返し処理も、よく使われています。
例えば、下記のような配列があるとします。
arr = [1, 2, 3, 4, 5]
この配列の要素の全ての和を求める場合、次のように処理します。
sum = 0
sum = sum + arr[0]
sum = sum + arr[1]
sum = sum + arr[2]
sum = sum + arr[3]
sum = sum + arr[4]
見て解るように、同じ処理が繰り返されています。それなら、配列arrの要素を順に変数にコピーし、次のように書いた方が効率的です。
sum = sum + x
そして、配列arrの要素を順に変数にコピーし、処理を記述するのにeachが使えます。
arr.each do |x| sum = sum + x end
このように、配列の要素の数だけ処理するプログラムを書く場合、配列の要素を1つずつ記述するよりも、eachメソッドを使った繰り返し処理で書くことで、読み易く簡潔なプログラムを書くことが可能です。
eachメソッドの文法
今回紹介するeachメソッドは、配列クラスとハッシュクラスで利用可能です。次から、配列とハッシュで使われるeachメソッドの文法について紹介します。
配列のeachの文法
配列.each do | 変数 |
処理
end
配列の要素を、順に||内の変数で取り出し、続く処理で変数を用いたプログラムを記述します。
ハッシュのeachの文法
ハッシュ.each do | キーの変数、値の変数 |
処理
end
基本的にハッシュでも配列と同じですが、||内にキーと値の2つの変数を指定し、続く処理では、その2つの変数を使ったプログラムを記述できます。
ブロック構文は{}内でも書ける
先ほどRubyのブロック構文の書き方として、do~endを利用した例で紹介しましたが、{}で囲う書き方も可能です。厳密には、do~endと{}では機能が違いますが、通常のプロぐラミングで差はありません。どちらでが読み易いかで選んでください。
なお、eachメソッドを使った処理の中には、1行で書けるような簡単な処理でも使われます。そのような簡単な書き方では、{}を利用した方が読み易いでしょう。
ブロック構文に{}に使う例
arr = [1, 2, 3, 4, 5] sum = 0 arr.each { |x| sum += x } p sum
上の例と同じブロック構文をdo~endで書き直した例
arr = [1, 2, 3, 4, 5] sum = 0 arr.each do |x| sum += x end p sum
eachメソッドを使った例
先ほど紹介したように、eachメソッドは配列やハッシュを使ったRubyのプログラムでよく使われるメソッドです。そして、ブロック構文の中に、一般的なRubyのプログラムと同じ処理が書けます。
次から、配列のeachメソッドを使った繰り返し処理の例を紹介します。
ブロック構文内の変数に注意
ブロック構文の内部では、eachメソッドの前後の処理で使われている変数と、||の中で宣言した変数の他に、内部で定義した変数も使えます。ただし、ブロック構文の中で宣言した変数は、その外で参照できないので注意してください。
具体的には、下記の例を見てください。
arr = [1, 2, 3, 4, 5] sum = 0 arr.each do |x| d = 10 sum += x * d end p sum
これは、配列arrの要素に10をかけた数の合計を求めるRubyのプログラムです。eachメソッドに続くブロック構文の中では、その外で定義されたsumと、||の中に定義したx、さらにブロック構文の中で宣言したdが使えます。そして、ブロック構文の外では、計算結果が格納されたsumを表示できました。
しかし、ブロック構文の中で定義したdは、ブロック構文の外では使えません。ブロック構文の中で計算した結果を利用するためには、この例のようにブロックの構文の外側で定義した変数を使ってください。
ブロック構文の入れ子ができる
先ほど、eachメソッドのブロック構文の中は、一般的なRubyのプログラムと同じコードが書けます。そのため、ブロック構文の中で、eachメソッドを利用すれば、そのブロック構文を書くことが可能です。
ブロック構文の入れ子にした例を次に示します。
arr = [1, 2, 3, 4, 5] chk = [2,4] sum = 0 arr.each do |x| sw = 0 chk.each do |key| if x == key then sw=1 end end if sw == 0 then sum += x end end p sum
この例は、配列arrのeachメソッドのブロック構文の中に、配列chkのeachメソッドのブロック構文を入れ子に使った例です。この場合、配列chkのブロック構文の中では、その外側で宣言された変数swを利用できます。先ほど説明したように、その逆はできないので注意してください。
eachと似た機能のメソッド
Rubyには、eachの他に配列とハッシュのメソッドがたくさん用意されています。そして、それらを利用することで、eachメソッドのブロック構文で記述するよりも、簡潔に書くことが可能です。
次から、そのようなeachメソッドと似た機能のメソッドを紹介します。
mapメソッド
mapメソッドは、配列の各要素に対する演算を簡潔に書けるメソッドです。なお、mapメソッドは、ベースになる配列の要素を書き換えるので注意してください。
mapメソッドの文法
配列.map { |変数| 式 }
例えば、配列の全ての要素を100倍にするプログラムを、mapメソッドで次のように簡潔に書けます。
arr = [1, 2, 3, 4, 5] arr.map { |x| x * 100 } p arr # [100, 200, 300, 400, 500]が表示される
この例を、eachメソッドで書き直したのが次の例です。
arr = [1, 2, 3, 4, 5] out = [] arr.each { |x| out << x * 100 end arr = out put arr # [100, 200, 300, 400, 500]
この例では、配列arrの要素を計算した結果を配列outに出力し、最後にarrにコピーして先ほどのmapメソッドを使ったプログラムと同じ処理が可能です。
sumメソッド
sumメソッドは、配列の要素の合計を計算し、その値を返すメソッドです。
配列.sum { |変数| 式 }
sumメソッドの例
arr = [1, 2, 3, 4, 5] sum = arr.sum p sum # arrの要素の合計、15が表示される
また、ブロック構文を指定した場合、加算する前に、そのブロック構文を適用します。このような処理は、もちろんeachメソッドでも作れますが、sumメソッドでは次のように簡潔に記述可能です。
ブロック構文を適用したsumメソッドの例
arr = [1, 2, 3, 4, 5] sum = arr.sum {|x| x * 100 }
p sum # arrの要素に100をかけた値の合計、1500が表示される
まとめ
これまで説明したように、eachメソッドは、配列やハッシュを使った繰り返し処理でよく使われるメソッドです。そして、eachメソッドでは、ブロック構文内に配列やハッシュの要素を使ったプログラムを記述できます。
なお、eachメソッドで記述できる処理でも、他のメソッドを使った方が簡単に書けるケースもあります。ぜひ、eachメソッドの使い方をマスターして、Rubyらしい読み易いプログラムを書けるようなりましょう。