更新日:
【Ruby】 any?メソッドの便利な使い方や活用方法とは?
any?メソッドとは、配列などのコレクションの要素に1つでも真があればその時点でtrueを返し、全ての要素が偽ならfalseを返すメソッドです。
Rubyの場合は、nil
とfalse
は偽でそれ以外は全て真になります。
例えば、以下のコードのように配列の要素が全て偽ならfalse
が返り、配列の要素に1つでも真があればその時点でtrue
を返します。
1
2
3
4
5
irb(main):001:0> [nil, false].any? #全ての要素が偽なのでfalseが返る
=> false
irb(main):002:0> [10, nil, false].any? #10は真なのでtrueが返る
=> true
また、any?メソッドにブロックを伴う場合は、条件を指定する事が出来ます。条件を満たす要素が1つでもあればtrueを返し、条件を満たす要素が0の場合はfalseを返します。
1
2
irb(main):003:0> [100, 200, 300].any? { |v| v > 200 }
=> true
上記のブロックでは、「ブロック引数に渡された各要素の値は200より大きい」という条件を指定しており、レシーバの配列には200より大きい値があるのでtrue
が返ります。
any?メソッドは、条件を満たす要素が1つでもあるか判定する時に便利なメソッドなので使い方を理解していきましょう!
any?メソッドの使い方
any?メソッドの使い方をサンプルコードを用いて解説します。サンプルコードはirbで試す事が出来るので、是非手を動かしながら挙動を確認してみてください。
基本構文
any?メソッドは、オブジェクトにドット(.
)をつなげて使用します。
1
オブジェクト.any?
返り値は、true
やfalse
の真偽値を返します。
以下のコードのように要素の中に1つでも真があればtrue
を返します。
1
2
irb(main):001:0> [false, nil, 500].any?
=> true
他にもブロックや引数を使って、各要素と比較するオブジェクトや条件を指定する事が出来ます。
1
2
オブジェクト.any? { |ブロック引数| 条件 }
オブジェクト.any?(各要素と比較するオブジェクト)
それでは、any?メソッドの詳細な使い方をサンプルコードで1つ1つ見ていきます。
ブロックの省略
ブロックを省略して使う場合は、要素自体の真偽値を判定します。
1
オブジェクト.any?
例えば、以下のコードのように要素の中に1つでも真があればその時点でtrueを返し、全ての要素が偽だった場合はfalseを返します。
1
2
3
4
5
irb(main):001:0>[1, false, nil].any? #1が評価された時点でtrueを返す
=> true
irb(main):002:0>[false, nil].any? #全ての要素が偽なのでfalseを返す
=> false
Rubyでは、nil
とfalse
が偽でそれ以外は全て真になります。
以下のコードのように0
や空文字列(''
)は真になるので、any?メソッドはtrue
を返します。
1
2
3
4
5
6
7
8
9
10
11
irb(main):003:0> [nil, nil].any?
=> false
irb(main):004:0> [false, false].any?
=> false
irb(main):005:0> [false, 0].any? #0は真なのでtrueを返す
=> true
irb(main):006:0> [false, ''].any? #空文字列('')は真なのでtrueを返す
=> true
また、配列の要素がない場合は以下のコードのようにfalse
が返ります。
1
2
irb(main):007:0> [].any?
=> false
ブロックを伴う場合
ブロックを省略した場合は要素そのものを判定していましたが、ブロックを伴う場合はブロックの戻り値を判定します。ブロックには、判定する条件を指定する事が出来ます。
1
オブジェクト.any? { |ブロック引数| 条件 }
条件に「各要素の値は100より大きい」と指定した例で見ていきましょう。
以下のコードのように記述すると、配列の各要素はブロック引数v
に渡されて100より大きい要素か判定されます。全ての要素が条件を満たしてないのでfalse
が返ります。
1
2
irb(main):001:0> [0, 50, 100].any? { |v| v > 100 }
=> false
一方で以下の配列の場合は、条件を満たす要素が1つ以上あるのでtrue
が返ります。
1
2
irb(main):002:0> [100, 200, 300].any? { |v| v > 100 }
=> true
ブロックが真を返した時点で、ただちにtrue
を返し処理を中断するので、上記のコードではブロック引数に200を渡して、ブロックの戻り値として真が返った時点でtrue
が返されます。
また、ブロックの条件には以下の偶数か判定するeven?
のようにメソッドを使うことも出来ます。
1
2
irb(main):003:0> [100, 200, 300].any? { |v| v.even? }
=> true
上記のコードは、一定の条件をクリアすれば以下のコードのようにブロックを渡す代わりに&:メソッド名
で省略して書くことが出来ます。
1
2
irb(main):004:0> [100, 200, 300].any?(&:even?)
=> true
条件については、省略する書き方の3つ条件とは?を参考にしてください。
引数を使う場合
引数を使う場合は、引数に渡したオブジェクトと各要素が一致するか判定します。引数のオブジェクトと一致する要素が1つ以上あればtrue
を返し、全ての要素が一致しなければfalse
を返します。
1
オブジェクト.any?(各要素と比較するオブジェクト)
これは、各要素に対して要素 === 引数のオブジェクト
が評価されています。
例えば、以下のコードのように引数に1
を渡して実行すると、100 === 1
,200 === 1
のように各要素が1
と一致するか比較されます。
1
2
irb(main):001:0> [100, 200].any?(1)
=> false
上記のコードでは、全ての要素が1
と一致しないのでfalse
が返ります。
また、以下のコードのように引数にIntegerを渡して各要素に整数の数値オブジェクトが1つ以上あるか確認する事が出来ます。
1
2
3
4
irb(main):002:0> [100, 200].any?(Integer)
=> true
irb(main):003:0> ["100", "200"].any?(Integer)
=> false
if文と併用して使う
any?メソッドはif文と併用すると、結果によって処理を分ける事が出来るので便利です。
ブロックを省略した場合は、以下のコードのように「要素に1つ以上の真がある場合」と「全ての要素が偽だった場合」の処理を分ける事が出来ます。
1
2
3
4
5
if オブジェクト.any?
# 要素に1つ以上の真がある場合の処理
else
# 全ての要素が偽だった場合の処理
end
1
2
3
4
5
6
if [1, false, nil].any?
p "要素に1つ以上の真がある"
else
p "全ての要素が偽である"
end
# => "要素の中に1つ以上の真がある"
また、以下のコードのようにブロックを伴う場合は「条件を満たす要素が1つ以上ある場合」と「条件を満たす要素がない場合」の処理を分ける事が出来ます。
1
2
3
4
5
6
7
8
scores = [40, 55, 78]
if scores.any? { |score| score > 80 }
p "80より大きいスコアが存在します。"
else
p "80より大きいスコアは存在しません。"
end
# => "80より大きいスコアは存在しません。"
Railsで使う場合
any?メソッドはRailsでActiveRecordのメソッドと併用すると、便利なメソッドを作成する事が出来ます。
例えば、以下の画像のユーザーを管理をするusersテーブルには、ユーザーが退会したかのデータを扱うboolean型のdeleted
カラムがあります。データベースではtrueを1
、falseを0
で管理します。
カラムの値が1
だと退会している状態なので、現在は退会しているユーザーはいません。
以下のコードのように、updateメソッドを使って橋下さんを退会させてみます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[1] pry(main)> user = User.first
=> #<User:0x00007fc8dc6d7e80
id: 1,
name: "橋下",
age: 18,
deleted: false> # falseなので退会してない状態
[2] pry(main)> user.update(deleted: true) # trueに変更して更新する
=> true
[3] pry(main)> user
=> #<User:0x00007fc8dc6d7e80
id: 1,
name: "橋下",
age: 18,
deleted: true> # trueなので退会した状態
以下の画像のように、データベースでも退会を確認する事が出来ますね。
前置きが長くなりましたが、退会しているユーザーが存在するかどうか調べたい場合は、以下のコードのようにActiveRecordのwhereメソッドにany?メソッドを併用します。
1
2
3
pry(main)> User.where(deleted: true).any?
SELECT 1 AS one FROM `users` WHERE `users`.`deleted` = TRUE LIMIT 1
=> true
先ほど橋下さんを退会させたので、true
が返りますね。
上記のコードは、以下のコードのようにメソッドを作成すると使い回す事が出来ます。
1
2
3
def deleted_user_exists?
User.where(deleted: true).any?
end
上記のメソッドは真偽値を返すメソッドなので、deleted_user_exists?
のように名前の末尾に?
を付けます。
また、if文を使って以下のように条件分岐する事も出来ます。
1
2
3
4
5
6
if deleted_user_exists?
p "退会者はいます。"
else
p "退会者はいません。"
end
# => "退会者はいます。"
any?メソッドはRubyのメソッドですが、Railsには指定した条件のレコードがデータベースに存在するか確認するexistsメソッドもあるので興味がある方はexists?メソッドの基礎から応用の使い方を参考にして下さい。
この記事のまとめ
- any?メソッドとは、要素そのものを判定し真偽値を返すメソッドのこと
- 配列などのコレクションの要素に1つでも真があればその時点で
true
を返し、全ての要素が偽ならfalse
を返す - ブロックを伴う場合は、条件を満たす要素が1つでもあれば
true
を返し、なければfalse
を返す