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

时间:2017-04-22 11:29:10

标签: function f# sequence elements

我正在努力编写一个函数,它需要一个序列,比如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#而且我不擅长创建高阶函数和类似的东西,这就是为什么我在挣扎。

1 个答案:

答案 0 :(得分:4)

如果您遇到更高阶函数的问题以及如何撰写它们, 写下你想要应用的转换通常会有所帮助。

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

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

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

Seq.minBy (calcScoreAfterRemovingElement s) s

这是简写:

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

我们映射元素=&gt;到过滤的序列=&gt;到相应的值并返回最小值。

例如,如果我们使用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