😸

[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 を利用するコードも提示されています
(1..).lazy.enum_for(:inject, 0).map {|a, b| a + b }.take(10).force
# => [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
  • あったら便利そうと思いつつ、どういうときに利用するんだろう?みたいなことを言われるとむずかしい
  • 現時点でこれは Ruby 本体には導入されていないです
GitHubで編集を提案

Discussion