gpt4 book ai didi

f# - 在 F# 中执行 tryMax 和 tryMin 的最佳方法?

转载 作者:行者123 更新时间:2023-12-03 15:54:40 30 4
gpt4 key购买 nike

假设我有一个 seq如果有任何元素或 None,我想返回最大的除此以外。 F# 似乎没有这个内置。

这是我的尝试:

let tryMax xs = 
if Seq.isEmpty xs
then
None
else
Seq.max xs |> Some

let tryMin xs =
if Seq.isEmpty xs
then
None
else
Seq.min xs |> Some
  • 这种方法有什么问题吗?
  • 是否有内置的解决方案?
  • 最佳答案

    我认为你的方法总体上是好的。有一个现在已删除的答案建议使用 try/with通过捕获空序列的错误来防止对第一项进行双重评估,但这也可能很昂贵。

    如果你想防止双重评估,你可以使用 Seq.cache ,或不使用 Seq完全(使用 ListArray 代替)。或者使用 fold,它只迭代一次:

    module Seq =
    let tryMin sq =
    sq
    |> Seq.fold(fun x y ->
    match x with None -> Some y | Some x -> Some(min x y)) None

    用法:
    > Seq.tryMin Seq.empty<int>;;
    val it : int option = None

    > Seq.tryMin (Seq.singleton 2L);;
    val it : int64 option = Some 2L

    > Seq.tryMin (seq { 2; 3});;
    val it : int option = Some 2

    > Seq.tryMin (seq { 2; -3});;
    val it : int option = Some -3

    一种可能更快的方法(我没有计时)是防止创建 option在每个最小或最大计算结果上,同时防止第一项的多次迭代。

    这也应该有更少的 GC 压力;)。

    module Seq =
    let tryMin (sq: seq<_>) =
    use e = sq.GetEnumerator()

    // this returns false if there is no first item
    if e.MoveNext() then
    let mutable result = e.Current
    while e.MoveNext() do
    result <- min e.Current result

    Some result
    else
    None

    用法:

    > Seq.tryMin Seq.empty<int>;;
    val it : int option = None

    > Seq.tryMin (Seq.singleton 2L);;
    val it : int64 option = Some 2L

    > Seq.tryMin (seq { 2; 3});;
    val it : int option = Some 2

    > Seq.tryMin (seq { 2; -3});;
    val it : int option = Some -3

    关于f# - 在 F# 中执行 tryMax 和 tryMin 的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62082930/

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