F# 查找序列中所有元素的函数的最低结果

F# Finding lowest outcome of a function for all elements in a Sequence

我正在努力编写一个函数,它接受一个序列,比如说 Hand= {C2; H8; DK; S1},然后通过首先删除一个元素找到最小的整数结果,然后使用我命名为 CalculateScore() 的函数来查找那个新序列的分数。 它对 Sequence 中的所有元素执行此操作,但仅删除该 1 个元素,而不是之前的元素,因此 1st 运行 它将删除 C2 并计算分数,然后它将删除 H8(不删除 C2)并计算分数.一旦计算出所有分数,它就需要找到具有最低值的分数和 return 该元素。

这是我所指的一个非常暴力的非 F# 伪代码示例:

Hand= {C2; H8; DK; S1}, i = 0
NewHand = Hand[i].remove
Score = CalculateScore(newHand)
elementIndex = i
i++
NewHand = Hand[i].remove
if Score > CalculateScore(NewHand) 
    then Score = NewHand, elementIndex = i
i++
.........
return elementIndex

我做 F# 的时间不长,我不太擅长创建高阶函数和类似的东西,这就是我苦苦挣扎的原因。

当您遇到高阶函数问题以及如何组合它们时, 从写下您希望应用的转换开始通常会有所帮助。

let calcScoreAfterRemovingElement s el =
    s
    |> Seq.filter ((<>) el)
    |> calcScore

这里我们从序列中删除一个元素,然后计算得分。

现在,要将此转换应用于列表中的每个元素并计算最小值,我们可以简单地:

Seq.minBy (calcScoreAfterRemovingElement s) s

shorthand 用于:

Seq.minBy (fun el -> calcScoreAfterRemovingElement s el) s

当我们将元素 => 映射到过滤后的序列 => 到它们对应的值和 return 最小值时。

例如,如果我们使用 calcCard 函数而不是 calcScore,那么我们可以:

let calcScoreAfterRemovingElement s el =
    s
    |> Seq.filter ((<>) el)
    |> Seq.sumBy calcCard

这里去掉(当前)元素,映射过滤序列的元素 到它们对应的值并求和。

编辑

您可以使用 Seq.findIndexSeq.tryFindIndex 获取索引, 但这会破坏管道。让我们尝试一种不同的方法:

Seq.minBy (calcScoreAfterRemovingElement s) s

=

s
|> Seq.map (calcScoreAfterRemovingElement s)
|> Seq.min

正在获取索引

s
|> Seq.map (calcScoreAfterRemovingElement s)
|> Seq.indexed
|> Seq.minBy snd
|> fst

=

s
|> Seq.mapi (fun i el -> i , calcScoreAfterRemovingElement s el)
|> Seq.minBy snd
|> fst