答えて
を返す必要がありますが、それは答えが複数の文であることをOKであれば、これは次のようになり片道
a = [1, 2, 3, 4]
a.inject([]) { |x, y| x + [(x.last || 0) + y] }
ですクリーナー:
outp = a.inject([0]) { |x, y| x + [x.last + y] }
outp.shift # To remove the first 0
irb> a = (1..10).to_a
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb> a.inject([0]) { |(p,*ps),v| [v+p,p,*ps] }.reverse[1..-1]
#=> [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
また、Haskellのからノートを取り、scanrのルビーバージョンを作ることができます。
irb> class Array
> def scanr(init)
> self.inject([init]) { |ps,v| ps.unshift(yield(ps.first,v)) }.reverse
> end
> end
#=> nil
irb> a.scanr(0) { |p,v| p + v }
=> [0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
irb> a.scanr(0) { |p,v| p + v }[1..-1]
=> [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
irb> a.scanr(1) { |p,v| p * v }
=> [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
+1をscanrに参照すると、それは蓄積された注入です。配列Arrayの代わりにEnumerableモジュールにscanrを追加できることに注意してください。 – tokland
もう一つのアプローチ(私はkhell年代を好むが)
(1..10).inject([]) { |cs, i| cs << i + (cs.last || 0) }
私は私の答えを投稿した後hrntによって投稿答えを見ました。 2つのアプローチは同じように見えますが、各注入サイクルで同じアレイが使用されるため、上記のソリューションはより効率的です。
a,r = [1, 2, 3, 4],[]
k = a.inject(r) { |x, y| x + [(x.last || 0) + y] }
p r.object_id
# 35742260
p k.object_id
# 35730450
あなたはrとkが違うことに気づくでしょう。上記のソリューションと同じテストを行う場合:
a,r = [1, 2, 3, 4],[]
k = a.inject(r) { |cs, i| cs << i + (cs.last || 0) }
p r.object_id
# 35717730
p k.object_id
# 35717730
rとkのオブジェクトIDは同じです。
cs.last.to_iに変更することもできますが、短くはないが読みやすいかもしれませんか? – TCSGrad
また、scanl
について読むことができます。必要な機能ですが、Rubyでは実装されていません。ここでは例と、それのサンプルソースコードです:http://billsix.blogspot.com/2008/11/functional-collection-patterns-in-ruby.html
UPD: 上記のリンクは死んでいるので、代わりに私は宝石の一部としてのWolfram MathematicaのFoldList[]のそれは私のRubyの実装「MLL」hereことができると言うだろうOPの目的のために簡略化することが列挙されている間:
def fold_list array
start = 0
Enumerator.new do |e|
array.each do |i|
e << start += i
end
end
end
irb> fold_list([1,2,3]).to_a
=> [1, 3, 6]
一の以上のアプローチのためにこれを発掘、アレイを修正することは、インプレース
class Array
def cumulative_sum!
(1..size-1).each {|i| self[i] += self[i-1] }
self
end
end
も一般化することができます。
def cumulate!(&block)
(1..size-1).each {|i| self[i] = yield self[i-1], self[i] }
self
end
>> (1..10).to_a.cumulate! {|previous, next| previous * next }
=> [1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
は、私たちが望むHaskellの関数はscanl
、ないscanr
ある
[1,2,3,4].inject([]){ |acc, value| acc << acc.last.to_i + value.to_i }
=> [1, 3, 6, 10]
このコードを試してみてください。
class Array
def scanl(init)
self.reduce([init]) { |a, e| a.push(yield(a.last, e)) }
end
end
[1,2,3,4].scanl(0) { |a, b| a + b }[1..-1]
=> [1, 3, 6, 10]
- 1. pandas.DataFrame内の列の逆累積合計
- 2. 2列の累積合計値
- 3. 累積合計と列のパーセンテージ?
- 4. Findとの累積合計
- 5. Sparkの累積合計
- 6. JasperReports - クロスタブフッターの累積合計
- 7. SPARQLの累積合計
- 8. Tensorflowのn累積合計
- 9. MySQLの累積合計
- 10. 形状の配列の累積面積を計算する
- 11. numpy配列の逆累積合計を実行
- 12. Spotfireランニングバランス(累積合計)
- 13. SASコンディション累積合計
- 14. MySQL:NULLs行の累積合計の計算
- 15. 累積合計の計算方法は?
- 16. 異なる日の累積合計数
- 17. 累積/集計/合計リスト - Python
- 18. HTMLフォームのJavaScript、合計リアルタイムの累積
- 19. 前の行の累積合計
- 20. 最後の5行の累積合計
- 21. 毎月のMySQLの累積合計
- 22. ダミー変数の累積合計をR
- 23. Yii2グリッドビューの累積/ランニング合計
- 24. パワーBI(DAX)のグループ別累積合計
- 25. Pythonの加重累積合計
- 26. SASの条件付き累積合計
- 27. SQLの累積合計時間
- 28. 2つの列で累積合計を更新する
- 29. 累積的計算
- 30. 累積合計オブジェクト属性ストリーム
私自身、わずか5.5年後です! – Peter