こんにちは、鈴木です。
Ruby のコレクションクラスは Enumerable モジュールを include しています。
そして、Enumerabule モジュールにはコレクションを扱う上で非常に便利なメソッドが数多く提供されています。
今回はその中から、コレクションの中に「特定の条件を満たす要素が存在するかどうか」を判定する述語メソッドをまとめます。
便利な述語メソッド
Enumerable#any? を筆頭に、コレクションに対して「条件を満たす要素はあるのか?」、「いくつあるのか?」を判定するメソッドには以下のものがあります。
メソッド | 説明 |
---|---|
all? | 全ての要素が条件を満たす場合に true。要素が 0 の場合も true。 |
none? | 条件を満たす要素が 1 つも存在しない場合に true。要素が 0 の場合も true。 |
any? | 条件を満たす要素が 1 つ以上存在する場合に true。要素が 0 の場合は false。 |
one? | 条件を満たす要素が 1 つだけある場合に true。 |
many? | 条件を満たす要素が 2 つ以上ある場合に true。このメソッドは ActiveSupport で定義されています。 |
many? だけは ActiveSupport で定義されていることに注意しましょう。
使用例
上記メソッドはブロックを指定した場合はブロックの戻り値、そうでない場合はコレクションの要素の真偽によって判定します。
all? を例に使い方を見てみましょう。
まずはブロックを指定しない場合です。
1 2 3 4 5 |
# 全ての要素が真であるか判定する. ['1234567', 'abcdefg'].all? # => true # 全ての要素が真であるか判定する. ['1234567', 'abcdefg', nil].all? # => false |
次にブロックを指定する場合です。
1 2 3 4 5 6 7 |
# 5 教科のテスト結果が全て 30 点以上であるか判定する. points = {'国語' => 70, '数学' => 90, '理科' => 85, '社会' => 29, '英語' => 65} points.all?{|name, point| point >= 30} # => false # 全てのパスワードが 6 文字以上であるか判定する. passwords = ['1234567', 'pass'] passwords.all?{|s| s.length >= 6} # => false |
他のメソッド(none?, any?, one?, many?)の使い方も同様です。
1 2 3 4 5 6 7 8 9 10 11 |
# 要素数 0 の場合. [].one? # => false [].many? # => false # 要素数が 1 の場合. [:a].one? # => true [:a].many? # => false # 要素数が 2 の場合. [:a, :b].one? # => false [:a, :b].many? # => true |
コレクションが空の場合
コレクションが空の場合の結果は以下のようになります。
1 2 3 4 5 |
[].all? # => true [].none? # => true [].any? # => false [].one? # => false [].many? # => false |
慣れないうちは「コレクションが空の場合の戻り値はなんだっけ?」となることがあるので、きちんと把握しておきましょう。
まとめ
今回は「述語メソッド」という切り口で見てきましたが、Enumerable には便利なメソッドが多数存在します。
別の機会にそれらのメソッドもご紹介したいと思います。