😸
[Feature #17016] Enumerable#accumulate を追加する提案
[Feature #17016] Enumerable#accumulate
-
Enumerable#accumulate
を追加する提案- 起票されたのは5年前なので結構古めです
- もともと
#scan_left
という名前で提案されていて議論された結果#accumulate
という名前に変更されたみたい
- 挙動としては
Enumerable#inject
と似ているんですが#inject
が結果を返すのに比べて#accumulate
は呼び出されたブロックの結果の配列を返す形になります
[1, 2, 3].inject(0, &:+) # => 6
[1, 2, 3].accumulate(0, &:+) # => [0, 1, 3, 6]
- 代替案として次のようなコードが提示されていますがこれだと単純に
#lazy
が利用できない弊害とかがあるみたいですね
[1, 2, 3].inject([0]) { |a, e| a << a.last + e } # => [0, 1, 3, 6]
[1, 2, 3].each_with_object([0]) { |e, a| a << a.last + e } # => [0, 1, 3, 6]
(1..).lazy.inject([0]){ |a, e| a << a.last + e } # => infinite loop
(1..).lazy.each_with_object([0]){ |e, a| a << a.last + e } # => infinite loop
(1..).lazy.scan_left(0, &:+) # => Lazy enumerator
-
#lazy
のコンテキストでは以下のように#enum_for
を利用するコードも提示されています- https://bugs.ruby-lang.org/issues/17016#note-14
-
#enum_for
を経由することで擬似的にlazy.inject
を実現してるぽい?
(1..).lazy.enum_for(:inject, 0).map {|a, b| a + b }.take(10).force
# => [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
- あったら便利そうと思いつつ、どういうときに利用するんだろう?みたいなことを言われるとむずかしい
- matz も言及してた
- https://bugs.ruby-lang.org/issues/17016#note-17
- 現時点でこれは Ruby 本体には導入されていないです
Discussion