只是天真地使用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) –