gpt4 book ai didi

f# - 用于测试单例序列的 Seq.exactlyOne 的非抛出版本

转载 作者:行者123 更新时间:2023-12-04 22:57:26 25 4
gpt4 key购买 nike

更新 :我为此创建了一个 UserVoice 请求:Expand on the Cardinality functions for Seq .

我需要 Seq.exactlyOne 的功能,但具有 Some/None 语义。换句话说,我需要 Seq.head ,或者,如果序列为空或包含多个项目,我不需要任何东西。使用 Seq.exactlyOne在这种情况下会抛出。

我不认为有一种内置的方式来获得它(尽管这听起来很微不足道,以至于人们会期望 Seq.singleton 有一个对应物)。我想出了这个,但感觉很复杂:

let trySingleton sq = 
match Seq.isEmpty sq with
| true -> None
| false ->
match sq |> Seq.indexed |> Seq.tryFind (fst >> ((=) 1)) with
| Some _ -> None
| None -> Seq.exactlyOne sq |> Some

给出:
> trySingleton [|1;2;3|];;
val it : int option = None
> trySingleton Seq.empty<int>;;
val it : int option = None
> trySingleton [|1|];;
val it : int option = Some 1

有没有更简单,甚至内置的方法?我可以 try/catch Seq.exactlyOne ,但那是围绕异常构建业务逻辑,我宁愿不要(而且它很昂贵)。

更新:
我不知道 Seq.tryItem函数,这将使这更简单:
let trySingleton sq =
match sq |> Seq.tryItem 1 with
| Some _ -> None
| None -> Seq.tryHead sq

(好多了,但还是觉得有点别扭)

最佳答案

为什么不通过命令式处理枚举器来解决这个问题呢?

let trySingleton' (xs : seq<_>) =
use en = xs.GetEnumerator()
if en.MoveNext() then
let res = en.Current
if en.MoveNext() then None
else Some res
else None

trySingleton' Seq.empty<int> // None
trySingleton' [1] // Some 1
trySingleton' [1;2] // None

关于f# - 用于测试单例序列的 Seq.exactlyOne 的非抛出版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39628567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com