TaKesso's Tech Blog

Web中心の技術メモ

Ruby: Enumerableモジュール

REx - Ruby Examination で解いた問題の解説を自分なりにまとめ直すシリーズです。

問題

以下の実行結果として正しいものを選択しなさい。

p [1, 2, 3].inject{|x, y| x + y ** 2} rescue p $!
p [1, 2, 3].inject(0){|x, y| x + y ** 2} rescue p $!
p [1, 2, 3].inject([]){|x, y| x << y ** 2} rescue p $!
p [1, 2, 3].inject do|x, y| x + y ** 2 end rescue p $!

選択肢

選択肢 1行目 2行目 3行目 4行目
[1] 14 14 [1, 4, 9] 14
[2] 14 0 [] 14
[3] 14 14 [1, 4, 9]
[4] 14 [1, 4, 9]

解答

正解は [3] です

解説

inject(init = self.first) {|result, item| ... } -> object

  • 最初に初期値 init と self の最初の要素を引数にブロックを実行します。
  • 2 回目以降のループでは、前のブロックの実行結果と self の次の要素を引数に順次ブロックを実行します。
  • そうして最後の要素まで繰り返し、最後のブロックの実行結果を返します。

引用: instance method Enumerable#inject (Ruby 2.1.0)

1行目

begin
  [1, 2, 3].inject {|x, y|
    print sprintf("%d + %d ** 2 = ", x, y)
    p x + y ** 2
  }
rescue
  p $!
end
1 + 2 ** 2 = 5
5 + 3 ** 2 = 14

2行目

begin
  [1, 2, 3].inject(0) {|x, y|
    print sprintf("%d + %d ** 2 = ", x, y)
    p x + y ** 2
  }
rescue
  p $!
end
0 + 1 ** 2 = 1
1 + 2 ** 2 = 5
5 + 3 ** 2 = 14

3行目

begin
  [1, 2, 3].inject([]) {|x, y|
    print sprintf("%s << %d ** 2 = ", x.to_s, y)
    p x << y ** 2
  }
rescue
  p $!
end
[] << 1 ** 2 = [1]
[1] << 2 ** 2 = [1, 4]
[1, 4] << 3 ** 2 = [1, 4, 9]