LoginSignup
282
247

More than 5 years have passed since last update.

selectなどの配列の抽出・検索を行うメソッドまとめ

Last updated at Posted at 2015-07-15

Rubyでは配列やハッシュに抽出や検索の機能を与えることができるEnumerableというモジュールがあります。
ArrayやHashがselectメソッドを使えるのも、このモジュールのおかげです。

というわけで、Enumerableに実装されているもののうち、配列の抽出/検索系のメソッドをまとめてみました。

select / find_all

{}ブロック内の式が trueになる要素だけ を抽出します。
find_allselect と同義です。

なお、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になった 最初の要素 を検索して返します。
detectfind と同義です。

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には配列の操作やグループ分けなど、上記以外にも様々なメソッドが用意されています(別記事にまとめました)。
必要な場面でそれらのメソッドを思いつけるようになりたいですね。

282
247
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
282
247