🎃

【Ruby】ブロックで使う配列メソッド

2020/11/23に公開

実務入りたての頃にチェリー本で勉強した備忘録。
公開したほうが外部の目も入っていいかなと。

each

配列の繰り返し処理で最もよく使われるメソッド。
要素を一つずつ取り出し、ブロック内の処理を行う。

items = [1, 2, 3, 4, 5]
sum   = 0

# 各要素を足していく
items.each { |i| sum += i }

sum # => 15

each_with_index / each.with_index

each文の処理にインデックスの数字をつけたい場合に使用。
each.with_indexは引数にインデックスを開始する数値を指定できる。

[5, 10, 15].each_with_index do |n, i|
  p [n, i]
end
# => [5, 0]
#    [10, 1]
#    [15, 2]
[5, 10, 15].each.with_index(1) do |n, i|
  p [n, i]
end
# => [5, 1]
#    [10, 2]
#    [15, 3]

map / collect

eachメソッドとの違いは、各要素に対してブロック内の処理をした結果を新しい配列にして返す点。

items = [1, 2, 3, 4, 5]

# 各要素を2倍にして返す
double = items.map { |i| i * 2 }

double # => [2, 4, 6, 8, 10]

select / find_all

各要素に対してブロック内の処理をした結果、真の要素を集めた配列を返すメソッド。

items = [1, 2, 3, 4, 5]

# 偶数の要素を抽出する
even_numbers = items.select { |i| i.even? }

even_numbers # => [2, 4]

reject / delete_if

selectメソッドの反対で、真の要素を除外した配列を返す。

items = [1, 2, 3, 4, 5]

# 偶数の要素を除外する
odd_numbers = items.reject { |i| i.even? }

odd_numbers # => [1, 3, 5]
  • delete_ifは常にself(ここではitems)を返し、rejectselfを複製して、ブロックを評価した値が真になる要素を削除した配列を返す。
  • つまり上記処理後のitemsは、
    • reject => [1, 2, 3, 4, 5]
    • delete_if => [1, 3, 5]

find / detect

各要素に対してブロック内の処理をした結果、最初の真の要素を返すメソッド。

items = [1, 2, 3, 4, 5]

# 偶数の要素を抽出する
even_number = items.find { |i| i.even? }

even_number # => 2

inject / reduce

たたみ込み演算を行うメソッド。

items = [1, 2, 3, 4, 5]

# 各要素の足していく
sum = items.inject(0) { |n, i| n + i }

sum # => 15
  • ブロックの第2引数 i は、配列の各要素が順番に入る。
  • ブロックの第1引数 n は、初回のみinjectメソッドの引数 0 が入る。
  • 2回目以降はブロックの戻り値 n + i の結果が入り、結果的に各要素を足していく処理を行っている。
  • 少し視点を変えると下記のようなことを行っている。
(((((0 + 1) + 2) + 3) + 4) + 5) # => 15

Discussion