2011-06-23 79 views
2

我正在嘗試向Seq模塊添加一些額外的聚合函數。我一直在尋找的一些功能的實現這裏列出:Seq模塊中的聚合函數

https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/seq.fs

其中的免責條款存在的「這個函數返回,一旦該序列被反覆消化整個初始步驟的順序爲。這個函數的結果不應該與大的或無限的序列一起使用。「 許多功能都是如此,例如GroupBy。

  • 第一個問題:是否有方法來編寫可以有效處理大型序列的聚合函數?我知道「大」是主觀的;我只是尋找一般模式來編寫這樣的功能。

  • 第二個問題:我如何確保像Dictionary這樣的集合(在集合函數中定義的集合)被有效地垃圾收集?我知道字典應該在超出範圍時收集,但是有沒有一種方法可以明確表示?鑑於字典的範圍是保留在函數中,我不能在這個對話框中調用.Clear()。

+1

您需要什麼類型的聚合無法用Seq.fold來實現? – ildjarn

+0

SumBy函數怎麼樣?就像Seq 一樣,你可能想按第一列進行分組,然後按第二列進行分組..你可以做一個Seq.GroupBy和管道到Seq.Sum,但是性能很差.. – Bala

+0

http ://fssnip.net/5U? – ildjarn

回答

5

要回答你的第一個問題 - 在這種情況下,投入的問題是,整個序列具有功能之前處理像foldgroupBy可以給結果。有幾件事情可以做:

  • Seq.scan使用函數,聚合值就像fold但加入的每一個元素後產生電流狀態 - 結果也是序列,您可以laziliy消耗它(並獲得更多的和更精確的結果,例如)。

  • 在編寫返回seq<'a>的函數時,應該設計它們,以便從序列中獲取下一個元素僅消耗輸入的一些可預測數量的元素(但不是整個輸入序列)。這是不可能的,例如對於groupBy,但是您可以編寫類似分組的結構,該分組只能對同一組的相鄰元素進行分組。

要回答第二個問題 - 你通常不應該過分擔心垃圾回收器。在函數結束時強制垃圾收集可能會造成更多的傷害,而不僅僅依靠GC來良好工作。