Just do IT

思うは招く

Enumerable#inject 初期値ありなしの挙動の違い

レシーバが配列の場合

初期値がない場合

> [1, 2, 3].inject { |result, item| p result + item*2 }
5
11
=> 11
  • 初期値がない場合、先頭の要素と2番めの要素をブロックに渡す
  • 上記の場合、resultに1、itemに2が渡されており、item*2されていることから1+4になり、結果5になっている
  • 次に、resultには5、itemに3が渡されており、5+6となり、結果11になっている

それぞれの値を表示してみるとわかりやすい。

[1, 2, 3].inject do |result, item|
   p result
   p item*2
   p result + item*2
end

1
4
5
5
6
11
=> 11

初期値がある場合

> [1, 2, 3].inject(0) { |result, item| p result + item*2 }
2
6
12
=> 12
  • 初期値があるとき、この場合はresult0が渡されている
  • よって、最初は0(result) + 2(item*2)されているので、結果が2になっている
  • その次は2(result) + 4(item*2) = 6
  • その次は6(result) + 6(item*2) = 12

Enumerable#inject (Ruby 3.1 リファレンスマニュアル)

「Effective Ruby」によると、基本的には初期値を設定するのが望ましいとされている。