Search

検索したいワードを入力してください

2019年04月10日

Rubyでselectメソッドを使うための基本を解説

本記事では、Rubyにおける、配列やハッシュから、ブロック内で条件式を指定して、要素を抽出するselectメソッドについて紹介します。さらに、配列における、with_indexメソッドを用いた、ブロック内でのインデックスの取得方法についても紹介します。

Rubyのselectメソッドとは

Rubyのselectメソッドは、配列、ハッシュにおいて使用できます。ブロック内で条件式を指定して、真になる要素を抽出することができます。selectメソッドにはfind_allという別名もあります。また、これとは逆に、真になる要素を削除するrejectメソッドもあります。

mapメソッドとの違い

配列におけるmapメソッドでは、配列の各要素をブロック式によって変換を行います。よって、適用した後も要素数は変わりません。一方、selectメソッドでは、ブロックの戻り値で条件判定を行い、真ならば残し、偽ならば削除します。よって、偽の要素が存在する場合、元の配列とは要素数が減少します。

基本的なselectの書き方

Rubyにおけるselectメソッドの構文は以下の通りです。

<配列/ハッシュ>.select{|変数|条件式}

変数は、配列の場合、1つ指定して個々の要素、ハッシュの場合、2つ指定してキーと値を表します。

配列の場合

次のRubyスクリプトでは、配列にselectメソッドを適用しています。非破壊的メソッドを使用しているので、配列の内容は変更されません。

fruits=["Apple","Banana","Orange","Peach","Lemon","Kiwi","Pineapple"]

p fruits.select{|f|f.start_with?("P")} #=> ["Peach", "Pineapple"]
p fruits #=> ["Apple", "Banana", "Orange", "Peach", "Lemon", "Kiwi", "Pineapple"]

ハッシュの場合

次のRubyスクリプトでは、ハッシュにselectメソッドを適用しています。非破壊的メソッドを使用しているので、ハッシュの内容は変更されません。

fruits={"Apple"=>100,"Banana"=>120,"Orange"=>110,"Peach"=>120,"Lemon"=>90,"Kiwi"=>95,"Pineapple"=>135}

p fruits.select{|k,v|k.end_with?("e")}
#=> {"Apple"=>100, "Orange"=>110, "Pineapple"=>135}
p fruits.select{|k,v|v>=115}
#=> {"Banana"=>120, "Peach"=>120, "Pineapple"=>135}

p fruits #=> {"Apple"=>100, "Banana"=>120, "Orange"=>110, "Peach"=>120, "Lemon"=>90, "Kiwi"=>95, "Pineapple"=>135}

ハッシュにおけるselectメソッドは、結果もハッシュで返されます。単にキーだけの配列を得たい場合には、keysメソッドが使用できます。

p fruits.select{|k,v|v>=115}.keys #=> ["Banana", "Peach", "Pineapple"]

破壊的なselect!メソッド

selectに!をつけてselect!とすると、破壊的なメソッドとなります。これは、メソッドの結果を返すと同時に、それ自身を変更します。

fruits=["Apple","Banana","Orange","Peach","Lemon","Kiwi","Pineapple"]

p fruits.select!{|f|f.start_with?("P")} #=> ["Peach", "Pineapple"]
p fruits #=> ["Peach", "Pineapple"]

このメソッドは、ハッシュについても使用することができます。

fruits={"Apple"=>100,"Banana"=>120,"Orange"=>110,"Peach"=>120,"Lemon"=>90,"Kiwi"=>95,"Pineapple"=>135}

p fruits.select!{|k,v|k.end_with?("e")}
#=> {"Apple"=>100, "Orange"=>110, "Pineapple"=>135}
p fruits #=> {"Apple"=>100, "Orange"=>110, "Pineapple"=>135}

インデックスを扱う方法

配列においては、selectメソッドにwith_indexをつけると、ブロック内でその要素があるインデックスを取得できます。一方、ハッシュにはインデックスがないので、この方法は使えません。

with_indexメソッドを使った作例

以下のRubyスクリプトでは、まず、0~99の整数からなる配列について、シャッフルを行います。次に、インデックス番号より多い整数をselect.with_indexメソッドにより抽出し、その数を表示しています。

Rubyスクリプトを実行する際、コマンドライン引数によって、乱数の種を指定できますので、同じパターンを再実行することができます。

#*** array_index.rb ***
if ARGV[0]
begin
seed=Integer(ARGV[0])
rescue
abort"Invalid seed value: #{ARGV[0]}"
end
else
seed=Random.new_seed
end

nums=(0...100).to_a.shuffle(random: Random.new(seed))

nums.each_slice(10) do |row|
puts row.map{|n|"%2d"%n}.join(" ")
end

puts

puts"<インデックスより大きい要素>"
p nums_select=nums.select.with_index{|n,idx|n>idx}.sort

puts

puts "#{nums_select.length}個"

実行結果

$ ./array_index.rb 34
14 74 15 4 32 59 91 10 50 53
75 16 54 39 12 22 99 24 71 49
40 60 28 64 81 41 3 7 94 83
45 17 70 27 0 96 80 57 98 1
47 52 65 61 30 8 6 56 9 23
97 46 88 67 82 44 13 26 95 55
25 76 84 48 31 43 77 66 38 86
73 34 93 58 37 2 36 79 42 72
63 21 19 51 87 5 62 20 90 89
92 18 29 78 11 69 35 68 85 33

<インデックスより大きい要素>
[14, 19, 23, 26, 28, 30, 34, 36, 37, 38, 44, 46, 48, 49, 50, 51, 52, 54, 57, 59, 60, 61, 63, 65, 67, 68, 69, 70, 72, 74, 76, 78, 79, 80, 81, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 98, 99]

53個

単に配列の要素が条件を満たしているかだけを判定したい場合は?

Rubyでは、any?、all?、none?メソッドで、配列、ハッシュ内の要素について判定を行うことができます。以下の表は、これらのメソッドの機能をまとめたものです。

これらのメソッドは、selectメソッドを用いて抽出を行い、その長さを調べるという方法よりも効率的に行うことができます。先頭から順に見ていって、途中で真または偽の要素が見つかった場合、その時点で真偽が分かることがあるからです。

メソッド名内容
any?どれか一つでも満たしていれば真
all?どの要素も満たしていれば真
none?どの要素も満たしていなければ真

サンプルコード

nums=[1,4,2,1,3,1,5,7,6,5,2]

p nums.any?{|n|n==5} #=> true
p nums.all?{|n|n%2==1} #=> false
p nums.none?{|n|n==8} #=> true

fruits={"Apple"=>100,"Banana"=>120,"Orange"=>110,"Peach"=>120,"Lemon"=>90,"Kiwi"=>95,"Pineapple"=>135}

p fruits.any?{|k,v|v>=120} #=> true
p fruits.none?{|k,v|v<100} #=> false
p fruits.all?{|k,v|v<=150} #=>true

実行時間の計測

$ time ruby -e'p (1..100_000_000).to_a.any?{|n|n>0}'
true

real 0m8.244s
user 0m4.343s
sys 0m3.843s

$ time ruby -e'p !(1..100_000_000).to_a.select{|n|n>0}.empty?'
true

real 0m19.172s
user 0m13.890s
sys 0m5.233s

ブロックに条件式を使用するメソッドはいくつかある

本記事では、selectメソッドで、配列やハッシュの、条件を満たす要素を抽出する方法を紹介しました。さらに、with_indexメソッドを用いたインデックスの取得方法についても紹介しました。

selectメソッドは、すべての要素について判定を行います。単に配列の要素が条件を満たしているかを判定する場合は、any?、all?、none?メソッドを使用する方が効率的ですので、これらを使用しましょう。

【PR】多くの人がプログラミングを諦めてしまう理由をご存知ですか?



近年プログラミングを勉強する人が増えています。

プログラミング学習者の多くは独学から取り組もうとしますが、だいたい80%ほどは3ヶ月も続かずに諦めてしまいます。早い人は1日目で。

多くの人がプログラミングを独学しようとして諦める理由は、次の3つ。
●モチベーションが維持できない
●エラーの原因・解決方法が分からない
●どう学習すればよいか分からない

TechBoostというプログラミングスクールでは、みんなと一緒にプログラミングをするのでモチベーションの維持ができ、分からないことがあればマンツーマンで教えてくれ、徹底的に研究された初心者向けの教材が揃っています。

TechBoostを卒業後、実際にエンジニアとして転職した方もいるほど。

本気でプログラミングを学びたい方は、一度無料のカウンセリングでご相談ください。プログラミングを嫌いになる前に。

tech boostについて

オーダーメイド型の学習コンテンツを提供する「tech boost」 は、エンジニアのキャリア支援に特化したサービスを複数展開している株式会社Branding Engineerが運営しているプログラミングスクールです。最短3ヶ月間で、未経験から『プログラミングの基礎』、『実際に業務で必要となるスキル』、『今のトレンドとなっている知識』まで学べ、ご希望の方にはプロのキャリアアドバイザーによる就業支援を行うことができます。

tech boost卒業生インタビュー

tech boostの卒業生の声を聞きました。あなたがプログラミングを学びたい理由を、一度考えてみてください。
営業→Javaエンジニア→Rubyエンジニアと転向し、第一志望のFinTech企業で働く山下さん
元営業、ビジネスのわかるエンジニアを目指す菅原さん
サンフランシスコに交換留学し、シリコンバレーのVCでインターン中の梅本さん
予備校の営業から半年でエンジニア転職を果たした小田島さん

tech boostの口コミ



Related