Rubyでは配列やハッシュに抽出や検索の機能を与えることができるEnumerableというモジュールがあります。
ArrayやHashがselectメソッドを使えるのも、このモジュールのおかげです。
というわけで、Enumerableに実装されているもののうち、配列の抽出/検索系のメソッドをまとめてみました。
select / find_all
{}ブロック内の式が trueになる要素だけ を抽出します。
find_all
は select
と同義です。
なお、trueになる要素がない場合は空の配列が返ります。
# 2で割り切れるものを抽出する
[1, 2, 3, 4, 5, 6].select { |n| n % 2 == 0 }
# => [2, 4, 6]
# 9で割り切れるものがないので空の配列が返る
[1, 2, 3, 4, 5, 6].select { |n| n % 9 == 0 }
# => []
Hashでもこんな風に書けばいけます。
# valueが1のものを抽出する
{:a => 1, :b => 2}.select { |k, v| v == 1 }
# => {:a => 1}
reject
selectの反対で、{}ブロック内の式が falseになる要素だけ を抽出します。
これも、falseになる要素がない場合は空の配列が返ります。
# 2で割り切れるものじゃないものを抽出する
[1, 2, 3, 4, 5, 6].reject { |n| n % 2 == 0 }
# => [1, 3, 5]
# すべて1で割り切れるので空の配列が返る
[1, 2, 3, 4, 5, 6].reject { |n| n % 1 == 0 }
# => []
find / detect
{}ブロック内の式がtrueになった 最初の要素 を検索して返します。
detect
は find
と同義です。
trueになる要素がない場合はnilが返ります。
# 最初の3の倍数を探す
[1, 5, 8, 2, 6, 3].find { |n| n % 3 == 0 }
# => 6
# 7で割り切れるものがないのでnilが返る
[1, 5, 8, 2, 6, 3].find { |n| n % 7 == 0 }
# => nil
ちなみに、要素の位置を知りたい場合は find_index
を使えばOKです。
# 最初の3の倍数の位置を探す
[1, 5, 8, 2, 6, 3].find_index { |n| n % 3 == 0 }
# => 4
grep
grepの引数に マッチする要素だけ を抽出します。
引数には正規表現が使えます。
マッチする要素がない場合は空の配列が返ります。
# 数字を含むものを抽出する
['a1', 'bb', 'c2', 'dd', '5e'].grep(/[0-9]/)
# => ["a1", "c2", "5e"]
# 大文字の英語を含むものがないので空の配列が返る
['a1', 'bb', 'c2', 'dd', '5e'].grep(/[A-Z]/)
=> []
take_while
{}ブロック内の式が falseになる手前の要素まで を返します。
# 3が出るまで抽出する
[1, 2, 3, 4, 5, 6].take_while { |i| i < 3 }
# => [1, 2]
drop_while
take_whileの反対で、{}ブロック内の式が falseになった以降の要素すべて を返します。
# 3が出たらそれ以降を抽出する
[1, 2, 3, 4, 5, 6]. drop_while { |i| i < 3 }
# => [3, 4, 5, 6]
まとめ
Enumerableには配列の操作やグループ分けなど、上記以外にも様々なメソッドが用意されています(別記事にまとめました)。
必要な場面でそれらのメソッドを思いつけるようになりたいですね。