【Ruby】include?メソッドとall?メソッドの組み合わせ

毎日こつこつ取り組んでいるRubyドリル(全70問)も 気がついたら2周目中盤です。

今日は本日の朝活で発見した 「include?メソッドとall?メソッドを組み合わせた実装」 について書こうと思います。

include?メソッド

文字列や配列の要素に含まれる文字列に対して、指定した文字列が存在するか確認するときに使用する。

指定した文字列が

存在した場合はtrue

存在しない場合はfalse

をそれぞれ返す。

include?の書き方

オブジェクト名.include?("検索文字列")

⚠️Rubyには文字列を検索するinclude?の他にモジュールを呼び出すincludeがありますが、

本日は文字列を検索する方について書こうと思います。

本日の練習問題

include?を使って配列内に指定の数字が全て含まれているか調べるプログラムの実装。

  • 配列内に1,2,3が全て入っている場合は、「True」と出力

  • 配列内に1,2,3の全てが入っていない場合は「False」と出力

ここで私、下記のようにinclude?の()内に複数の要素を指定。

def array123(nums)
  if nums.include?(1, 2, 3)
    puts "True"
  else
    puts "False"
  end
end

array123([1, 1, 2, 3, 1])

すると、下記のエラーが返ってきました。

`include?': wrong number of arguments (given 3, expected 1) (ArgumentError)

このエラー文について読み解くと、

ArgumentError

これは「引数の数が合わないよー」というメッセージ。

エラーのカリキュラムで学習していたので、ここは理解。

wrong number of arguments (given 3, expected 1)

引数で求めている数が本来は1個(expected)なのに、3個与えられている(given)よ〜。

ここもエラーのカリキュラムで学習済み。

どうやらinclude?は「1つの要素」しか指定することができず、要素を複数指定することはできないらしい。

今回の問題の場合は、1, 2, 3全ての要素を指定する必要があるため、

include?のみを使用する場合は、&&演算子を複数使用する必要があるよう。

def array123(nums)
  if nums.include?(1) && nums.include?(2) && nums.include?(3)
    puts "True"
  else
    puts "False"
  end
end

array123([1, 1, 2, 3, 1])

私個人の感想としては、

「&&演算子を複数使用すると、見にくい…めんどくさい…」

この感想をなんとか解消するために、なんかまとめて打ち込んで返してもらえる方法ないかな〜と探していたら…

all?メソッドに遭遇!

all?メソッド

配列の要素を繰り返し実行し、ブロックの返り値が全て真の場合にtrueを返すメソッド。

all?の書き方

オブジェクト.all? { |要素| ブロック処理}

今回の練習問題みたいに3つの要素だけならまだ演算子を複数使うのでもいいと思うのですが、

存在を調べたい要素がたくさん合った場合とか、

配列の中に指定した要素より大きい値が存在するかとか、

そういう時にはこっちの方がスッキリしそうじゃない? これ使ってみよう!

ということで、書いてみました。

def array123(nums)
  array = [1, 2, 3]
  if array.all?{
      |n| nums.include?(n)
    }
    puts "True"
  else
    puts "False"
  end
end

array123([1, 1, 2, 3, 1])

探したい要素をarrayにお渡しして、

array.all?でarrayの中身全部入ってますか〜?という感じです。

ブロックの引数nに配列(array)の要素([1, 2, 3])を順番に格納しながら、

繰り返し条件式(nums.include?)を実行し、条件式が偽になった時点で処理を中断してfalseを返す仕組みです。

挙動を確認したら、しっかり動いてくれました。

1周目のRubyドリルでは模範回答を見て、こんなもん。って思ってましたが、

カリキュラムを進めながら、2周目のRubyドリルに取り組むと、

自分だったらこうした方が楽だなとか、

他の人が見る時こっちの方が見やすいのでは?とか、

いろんな視点を持って取り組むことができている気がします。

もちろん未経験の立場での意見なので、 これが実は良くないコーディング…とかもあるかもしれません。

どんどん質問して添削してもらおうと思います!