Rubyには、配列(Array)クラスで作れる配列オブジェクトを操作する便利なメソッドが幾つもありますが、条件に一致する要素の検索によく使われるメソッドがfindです。
配列オブジェクトには繰り返し処理を作成するeachメソッドがあり、それを使って作ることも可能です。とはいえfindメソッドを使えばシンプルに書けるので、ぜひ活用してください。今回はこのようなfindメソッドの使い方について例を使って解説します。
- 配列オブジェクトには要素を調べる便利なメソッドがあり、その1つがfindメソッド
- findメソッドではブロックでの中に条件を記述する
- findの代わりにdetectを使っても同じ
- findメソッドはハッシュのオブジェクトでも使える
- 配列オブジェクトではfindに似た機能のメソッドもある
配列はEnumerableモジュールが使われる
Rubyは、全ての要素がクラスで作られていますが、今回扱う配列はArrayクラスです。そして、配列には、Rubyの組み込みライブラリであるEnumerableモジュールが適用されます。今回紹介するfindメソッドは、このEnumerableモジュールの一部です。
そこでfindメソッドを説明する前に、その基になるEnumerableモジュールについて解説します。
Enumerableモジュールとは何か
Rubyでは、他のプログラミング言語と同じように配列(Array)やハッシュ(Hash)が使えます。なお、Rubyは全ての機能がクラスによって定義されているのが特徴ですが、配列(Array)も例外ではありません。そして、配列(Array)およびハッシュ(Hash)の機能を提供しているクラスが、Enumerableモジュールです。
なお、Enumerableモジュールは、Rubyをインストールすると自動的にシステムに組み込まれているので、すぐに利用できます。
Enumerableモジュールに多くのメソッドがある
Rubyで配列(Array)を作り、そのメソッドを使う際にマニュアルを調べようと思ったら、まずはEnumerableモジュールについて調べてみてください。きっと多くのメソッドがあることが解るでしょう。
今回紹介するfindは、Enumerableモジュールによって定義された、配列(Array)またはハッシュ(Hash)に対して実行するメソッドです。また、findの他、find_allやfind_indexといったメソッドも見つかります。次から、このfindメソッド、および、それと似た機能のメソッドについて解説します。
Rubyを学びたい方におすすめのスクールはこちら
findメソッドの基本
先ほど説明したように、findは、配列(Array)またはハッシュ(Hash)に対して実行するメソッドです。まずは、findの基本について解説します。
findメソッドの文法
findメソッドは、配列(Array)の要素に対して、ブロックを使ってそれを評価し、真になる最初の要素を返します。
findメソッドの文法
配列.find { |変数| 条件 }
ブロック内には、||内に配列の要素を代入する変数を宣言し、その変数を利用した条件を記載します。
findメソッドを使用例 p [1, 2, 3, 4, 5] find { |i| i % 2 == 0 }
この例では、[1, 2, 3, 4, 5]という配列から、2で割り切れる要素のうち、最初に見つかった要素を返す例です。条件には、||内で宣言した変数iに対して、「i % 2 == 0」を適用します。そして、この条件に一致する要素は、2と4ですが、最初に見つかったのは2なので、この例では2を表示します。
条件に一致した要素が無い場合
findメソッドを使用し、配列の要素を評価したものの、該当する要素が1つも無い場合は、nilを返します。ただし、findにifnoneを指定した場合は、ifnoneでデフォルトを設定した場合は、それが表示されます。
要素が無い場合の例 p [1, 1, 1, 1, 1] find { |i| i % 2 == 0 }
この場合は、条件に一致する要素が無いので、nilが表示されます。
ifnoneを指定した例 ifnone = proc { raise ArgumentError, "item not found" } p [1, 1, 1, 1, 1].find(ifnone) {|i| i % 2 == 0 }
この場合は、条件に一致する要素が無いものの、ifnoneが定義されているので、そのメッセージ「item not found」が表示されます。
findとdetectは同じ
英語のdetectには「検出する」という意味がありますが、Rubyでは、findと同じ機能のメソッドとして利用できます。
detectメソッドの文法
配列.detect { |変数| 条件 }
なお、detectはfindと同じ機能のため、配列の要素に対して、ブロックを評価した値が真になった最初の要素を返します。さらに条件に一致する要素が無い場合もfindと同じく、何も指定しない場合にはnilを、また、ifnoneを指定した場合は定義されたメッセージを返します。
Rubyを学びたい方におすすめのスクールはこちら
findメソッドの使用例
次に、Rubyの配列(Array)に対してfindメソッドを使った例と、ハッシュ(Hash)に対してfindメソッドを使った例で、findメソッドの使い方を紹介します。
配列に対するfindの使用例
Rubyにおけるfindメソッドの、配列(Array)の要素を評価し、一致する要素があれば最初に見つかった要素を返し、該当する要素が無ければnilを返す、という機能は、2次元の配列(Array)にも使えます。
次に、2次元の配列(Array)に対してfindを利用した例を紹介します。なお、この場合のfindは、条件に一致する最初に見つかった配列(Array)、または、nilを返すことから、それをifでチェックすることで、処理を切り替えます。
2次元の配列(Array)に適用した例 ar = [ [1, 'test', '1-1'], [2, 'example', '1-2'], [3, 'traial', '1-3'] ] one = ar.find { |val| val[0] == 1 } if one.nil? then puts one[0] puts one[1] puts one[2] end
この例れは、findの条件に一致する要素、[1, ‘test’, ‘1-1’] がoneに代入され、nilでは無いので、次のように出力されます。
1 test 1-1
ハッシュに対するfindの使用例
findメソッドは、ハッシュ(Hash)に対しても配列(Array)と同じように使えます。なお、ハッシュ(Hash)で使う場合は、ブロック内にキーとバリューの2つを参照できるように、次のように指定してください。
配列.find { | キー, バリュー | 条件 }
ただし、この場合、ブロック内に指定した「| キー, バリュー |」のペアの配列として返されます。そのため、findの出力には、配列の1番目にはキーの値が、また、2番目にはバリューの値が格納されているので注意してください。
次に、ハッシュにfindを適用した例を次に紹介します。
hash = { 1 => "1-1", 2 => "1-2", 3 => "1-3" } one = hash.find { |key, val| key = 2 } if ! one.nil? then puts "key = " + String(one[0]) puts "val = " + one[1] end
この例では、ハッシュ(Hash)のキーが2の要素をoneに代入します。そして、この場合、oneには、キーをバリューのペアの配列が代入されるので、one[0]でキーを、また、one[1]でバリューとして利用できます。
Rubyを学びたい方におすすめのスクールはこちら
findと似たメソッドとの違い
Rubyには、配列(Array)で使えるメソッドがたくさんあり、findに似たメソッドがあります。そして、そのようなメソッドの中でもfindで始まるメソッドがあるので、そのようなメソッドを紹介します。
・find_all
findメソッドは、評価して一致した要素の最初の1つを返しますが、find_allは、評価して一致した全ての要素を返すメソッドです。
・find_index
findは、要素そのものを返すメソッドでしたが、find_indexは、条件に一致する最初の要素の位置を返すメソッドです。
・first
firstメソッドは、配列(Array)の最初の要素を返すメソッドです。ただし、findと違い、ブロックに条件を書くことはできません。
まとめ
これまで解説したように、Rubyでは配列(Array)クラスに対して使えるメソッドがたくさんあり、その1つであるfindメソッドは、条件に一致する最初の要素を返すメソッドです。さらに配列(Array)だけではなくハッシュ(Hash)クラスにも使えますが、返される要素はキーとバリューの2つなので、戻り値の使い方は少し違います。
そして配列(Array)クラスとハッシュ(Hash)クラスには今回紹介したfindメソッドのように便利なメソッドがあり、機能が似たメソッドもあります。findメソッドの使い方をマスターしてうまく使い分けてください。
また、Rubyについてもっと詳しく学びたい方は、ポテパンキャンプの利用を検討されてはいかがでしょうか。
Rubyを学びたい方におすすめのスクールはこちら
Rubyの配列のメソッドには、別の名称でも同じ機能のものがあります。今回取り上げたfindとfind_allメソッドにも別名があるので、注意してください。