一千萬個為什麽

搜索

如何在列表中查找函數最大值的值

我想找到的不僅是應用於列表的函數的最大值(我將使用List.maxBy),而且還要找到列表中的值。這感覺就像一個相當普遍的操作,並且考慮到F#庫的豐富性,一般情況下我發現它實際上已經可用並不會感到驚訝,但如果是的話我似乎無法找到它!

To illustrate with an example, I want to be able to map a list domain and a function f

let domain = [0 .. 5]
let f x = -x * (x - 2)

(1,1)(因為應用於列表的其他元素的函數小於1)。

我第一次嘗試這個:

let findMaximum domain f =
    let candidates = [ for x in domain do
                        yield x, f x ]
    let rec findMaximumHelper domain f currentMax =
        match domain with
        | [] -> currentMax
        | head::tail -> 
            let cand = f head
            match currentMax with
            | None ->
                let newMax = Some(head, cand)
                findMaximumHelper tail f newMax
            | Some(maxAt, possMax) ->
                let newMax =
                    if cand > possMax then Some(head, cand)
                    else Some(maxAt, possMax)
                findMaximumHelper tail f newMax
    findMaximumHelper domain f None

let answer = findMaximum domain f

此時我意識到這非常接近 fold 操作,並放在一起

let findMaximum2 domain f =
    let findMaximumHelper f acc x =
        let cand = f x
        match acc with
        | None -> Some(x, cand)
        | Some(maxAt, possMax) ->
            if cand > possMax then Some(x, cand)
            else Some(maxAt, possMax)
    List.fold (findMaximumHelper f) None domain

let answer2 = findMaximum2 domain f

代替。

我的問題是,這些慣用的F#解決這個問題的方法,或者確實有更好的解決方法嗎?

最佳答案

實際上,F#庫提供了所有必要的高階函數來簡潔地表達:

domain
|> Seq.map (fun x -> x, f x)
|> Seq.maxBy snd

Note: updated to use Seq.map and Seq.maxBy instead of List.map and List.maxBy to address @ildjarn's concern about creating an unnecessary intermediate list.

轉載註明原文: 如何在列表中查找函數最大值的值