只是天真地使用Seq.length
可能不夠好,會炸燬無限序列。如何有效地找出一個序列是否至少有n個項目?
使用諸如ss |> Seq.truncate n |> Seq.length
之類的東西可以起作用,但幕後會涉及IEnumerator的MoveNext()
對參數序列塊的雙重遍歷。
我能弄出迄今最好的辦法是:
let hasAtLeast n (ss: seq<_>) =
let mutable result = true
use e = ss.GetEnumerator()
for _ in 1 .. n do result <- e.MoveNext()
result
這僅涉及單個序列移動(更準確地,在執行e.MoveNext()
n
次)和正確處理空和無限序列的邊界情況。我可以進一步拋出一些小的改進,比如顯式處理列表,數組和特定的例子,或者減少遍歷長度,但是想知道是否有更有效的方法來解決我可能會丟失的問題?
謝謝你的幫助。
編輯:hasAtLeast
功能,手邊5個整體實施變型(2我自己,通過2丹尼爾和一個接ANKUR建議建議)我給你佈置這些之間的馬拉松比賽。所有實施方案的結果都證明,Guvante是正確的:現有算法的最簡單組合是最好的,在過度工程中沒有任何意義。
的可讀性因素進一步投擲我會請使用我自己的純F#基礎的
let hasAtLeast n (ss: seq<_>) =
Seq.length (Seq.truncate n ss) >= n
或建議通過ANKUR完全等同基於的LINQ一個.NET的集成大寫
let hasAtLeast n (ss: seq<_>) =
ss.Take(n).Count() >= n
我不禁在想,如果你的算法應該使用更合適的類型,而不是遍歷序列。 – ChaosPandion
@ChaosPandion:相信我,我已經考慮過這件事。在我的辯護中,我想參考Luke Hoban標準偏差和基於事件的編程(http://blogs.msdn.com/b/lukeh/archive/2008/10/10/standard-deviation- and-event-based-programming.aspx) –