F#中检查序列投影值是否统一及是否存在内置实现
F# 内置函数相关结论
F# 核心库的Seq模块目前没有提供等价于你实现的、可直接校验「序列经投影后所有值是否统一」的开箱即用内置函数,需要自行实现该逻辑。
最优实现方案
你当前编写的实现逻辑是完全正确的,覆盖了空序列、单元素序列、多元素序列的所有边界场景,只是可以从性能角度做进一步优化:
- 你当前实现依赖
Seq.distinct判断值的差异性,该操作会在内部维护哈希集合记录所有已遍历的不同值,哪怕只需要找到2个不同值就终止流程,也会为每个遍历过的元素产生哈希计算、集合插入的开销,对于长序列存在不必要的性能损耗 - 更高效的实现不需要记录所有已出现的值,只需要记录序列第一个元素的投影值,后续逐个对比即可,只要碰到和首个值不同的投影,就立刻短路返回非统一结果,全程无额外堆分配
无冗余开销的实现示例:
module Seq = let isUniformBy (projection: 'T -> 'U when 'U : equality) (source: seq<'T>) = use enumerator = source.GetEnumerator() // 空序列场景 if not enumerator.MoveNext() then true else let firstProjected = projection enumerator.Current // 从第二个元素开始逐位对比 let rec checkRemaining () = if not (enumerator.MoveNext()) then true else let currentProjected = projection enumerator.Current currentProjected = firstProjected && checkRemaining() checkRemaining() let isUniform source = isUniformBy id source
该实现的行为和你原有代码的测试用例输出完全一致,在长序列场景下性能显著优于依赖Seq.distinct的实现。
内容的提问来源于stack exchange,提问作者sdgfsdh
相关产品推荐
相关产品推荐

