LoginSignup
2
0

More than 3 years have passed since last update.

Ruby 配列とブロックについて〜チェリー本4章〜

Last updated at Posted at 2019-05-01

Ruby 配列とブロックについて〜チェリー本4章〜

※この記事は初心者の私がチェリー本で学習するにあたって新しく知ったことや考えたことアウトプットするための場として書いています。
この記事は以下の情報を参考にして記述し、一部引用しています。
プロを目指す人のためのRuby入門

ブロックに使うメソッド

delete_if

irb(main):003:0> a = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):004:0> a.delete_if do |n|
irb(main):005:1* n.odd?
irb(main):006:1> end
=> [2, 4]

delete_ifメソッドはブロック内で指定した条件で配列の数字や文字等を削除するメソッドです。

irb(main):007:0> numbers = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):008:0> sum = 1
=> 1

irb(main):009:0> numbers.each do |n|
irb(main):010:1* sum_value = n.even? ? n * 10 : n 
irb(main):011:1> sum += sum_value
irb(main):012:1> end

irb(main):013:0> sum 
=> 70

このようにブロック内は複数行に渡って条件を書くことやブロック外からの参照も可能(ただしブロック内から外への参照は不可)。
sum_value = n.even? ? n * 10 : nあとブロックとは関係無いですが、最初この文の2つ目に出てくる?が何を意味してるものなのか意味がわからなかったですが、1つ目の?がeven?で一つのメソッドになっていて、2つ目の?は条件演算子の?です。

map

irb(main):035:0> numbers = [1,2,3,4]
=> [1, 2, 3, 4]
irb(main):036:0> new_numbers = numbers.map {|n| n * 10}
=> [10, 20, 30, 40]

他の配列を利用してブロック処理をしたもの新しい配列に作るメソッドです。

select / reject

even_numbers = numbers.select{|n| n.even?}
=> [2, 4]

irb(main):038:0> odd_numbers = numbers.reject{|n| n.odd?}
=> [2, 4]

selectはブロックの戻り値の中で条件式が一致したものだけを取り出すメソッドになります。
rejectは逆でブロックの戻り値の中で条件式が一致したものだけを除外するメソッドになります。

find

irb(main):040:0> find_numbers = numbers.find{|n| n.even?}
=> 2

ブロックの戻り値が最初に真になった最初の要素を返します。

each_with_index

drink = %w(coffee tee water cola)
=> ["coffee", "tee", "water", "cola"]

drink.each.with_index{|d, i| puts "#{i}:#{d}" }
0:coffee
1:tee
2:water
3:cola

drink.each.with_index(1){|d, i| puts "#{i}:#{d}"}
1:coffee
2:tee
3:water
4:cola

each文で処理する結果に.with_indexでインデックスの数字をつけてます。
インデックスの数字は指定しないと0から始まるので引数に1を指定してます。
簡単に書くとブロック処理の結果にもう一つ何か処理を一緒に加えたい時に使えるメソッドです。
ちなみにeach以外にもmapやdelete_ifと組み合わせてmap_with_indexやdelete_with_index,その他のメソッドと組み合わせて使うことができます。


リファクタリングに使える配列の書き方

do...endの代わりに{}を使う

numbers = [1,2,3,4]
numbers.each do |n|
sum += n
end
sum
=> 10

numbers.each {|n| sum += n}
sum
=> 10

ブロック内の条件式が1行で終わる場合はdo...endの代わりに{}を使って1行で終わらせる方が見やすいです。

(&:メソッド名)でもっと簡潔に書く

[1,2,3,4,5,].select{|n| n.even?}
=> [2, 4]
[1,2,3,4,5,].select(&:even?)
=> [2, 4]

1.ブロック引数が1つで
2.ブロックの中で呼び出すメソッドには引数が無く
3.ブロックの中ではメソッドを一回呼び出す以外の処理が無い
場合にのみこの方法が使えます!


あとがき

この記事でなんとか2日目も書くこともができた!
けど4時間もかかってしまった、主に記事構成を考えるのと記事のトピック毎にどのように書こうかというところに時間がかかってしまっているのでどうしようか...
このままだと時間の無い平日とかに続けるのが厳しそうなのでなんとか解決策を見つけます!
2日目でも既にただ本を読んでただけの頃と比べるとちゃんと自分の頭で考えて消化出来てると感じるので明日も書きます。

2
0
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
2
0