在F#中查找列表最大值的索引

在F#中查找列表最大值的索引

问题描述:

我正在尝试编写一个以列表为例的函数

I'm trying to write a function that takes a list for example

let list = [5;23;29;1] 
let x = max list // This will return 2 because 29 will be the max value and it's "indexed" at position 2

我不确定如何编写max函数

由于我的列表仅包含四个元素,因此我目前有一些类似的代码

Since my list will only contain four elements I currently have some code like this

let list = (1, newMap1 |> getScore) :: (2, newMap2 |> getScore) :: (3, newMap3 |> getScore) :: (4, newMap4 |> getScore) :: []

我认为这是一种可怕的方法,但是在找到(_, y)的最大值后,我仍然停留在如何返回(x, _)上.我对命令式方法非常有信心,但是我对如何在功能上做到这一点感到困惑

I consider this a terrible approach but I'm still stuck on how to return (x, _) after I find the max of (_, y). I'm very confident with imperative approaches but I'm stumped on how to do this functionally

有两种方法可以做到这一点.在底层,您可以编写一个递归函数来对列表进行迭代和模式匹配.如果您正在学习F#,这是一个很好的练习.

There is a couple of ways to do this. At the low-level, you can write a recursive function to iterate and pattern match over a list. This is good exercise if you are learning F#.

同样,您可以使用fold函数来实现.这里的想法是,我们保留一些状态,包括最佳值"和最佳值的索引.在每一步中,我们要么保留原始信息,要么对其进行更新:

Similarly, you can implement this using the fold function. Here, the idea is that we keep some state, consisting of the "best value" and the index of the best value. At each step, we either keep the original information, or update it:

let _, maxValue, maxIndex = 
  list |> List.fold (fun (index, maxSoFar, maxIndex) v -> 
    if v > maxSoFar then (index+1, v, index+1)
    else (index+1, maxSoFar, maxIndex)) (-1, System.Int32.MinValue, -1)

最后,我能想到的最短的选择是使用mapimaxBy函数:

Finally, the shortest option I can think of is to use mapi and maxBy functions:

list
|> Seq.mapi (fun i v -> i, v)
|> Seq.maxBy snd