我正在努力编写一个函数,它需要一个序列,比如说Hand= {C2; H8; DK; S1}
,通过第一次删除一个元素来找到最低的整数结果,然后使用我命名为 CalculateScore() 的函数来查找该新序列的分数。它对序列中的所有元素执行此操作,但仅删除该 1 个元素,而不是它之前的元素,因此第一次运行它将删除 C2 并计算分数,然后它将删除 H8(不删除 C2)并计算分数。一旦它计算了所有分数,它就需要找到具有最低值的那个并返回该元素。
这是我所指的一个非常暴力的非 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
这是以下的简写:
Seq.minBy (fun el -> calcScoreAfterRemovingElement s el) s
当我们将元素 => 映射到过滤序列时 => 到它们对应的值并返回最小值。
例如,如果我们使用calcCard
函数代替calcScore
,我们可以:
let calcScoreAfterRemovingElement s el =
s
|> Seq.filter ((<>) el)
|> Seq.sumBy calcCard
在这里,您删除(当前)元素,将过滤后的序列的元素映射到它们相应的值并将它们相加。
编辑
您可以使用Seq.findIndex
or获取索引Seq.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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句