如何在F#中的Seq,List或Array中查找max的索引

时间:2010-01-10 12:44:13

标签: f# functional-programming

Seq.max找到最大数量。我想要Seq.findIndex

之类的东西

Seq.maxIndex返回最大元素的索引。

2 个答案:

答案 0 :(得分:14)

我相信你正在寻找类似的东西:

let maxIndex seq = 
    fst (Seq.maxBy snd (Seq.mapi (fun i x -> i, x) seq))

请注意,为此函数提供一个空序列将导致ArgumentException。

(或者,以流水线方式编写:

let maxIndex seq =  
    seq
    |> Seq.mapi (fun i x -> i, x)
    |> Seq.maxBy snd 
    |> fst

答案 1 :(得分:3)

为什么不简单地使用

let l=[1;2;5;3];;
Seq.findIndex  (fun x -> x= Seq.max l) l ;;

也许正如Johan Kullbom在评论中所说:

"let m = Seq.max l in Seq.findIndex (fun x -> x = m) l"

如果你有点好O(n)

但是,获取索引的需要在我看来就像一个势在必行的“代码味道”

在FP中,通常最好在使用现有功能之前使用现有功能。 我现在这在C程序员的眼中看起来像是for(i(for(j)但我打赌你可能真的不需要知道索引,如果你开始在FP中思考。

或多或少是Finding index of element in a list in Haskell?

的副本

PS。 我无法抗拒。 在Haskell(ghc)中,方式应该类似于

let cmpSnd (_, y1) (_, y2) = compare y1  y2

let maxIndex l= fst $ maximumBy cmpSnd $ zip [0..] l

但是,由于F#中的zip似乎不允许zip具有不等长度的列表(?),因此可能需要使用mapi(我的F#中的haskell版本)

let cmpSnd xs=  snd xs ;;

let zipIndex a= Seq.mapi (fun i x -> i,x) a;;

let maxIndex seq=fst (Seq.maxBy cmpSnd (zipIndex seq));;

原因只是我可以列出一个清单

let l= [[0;199;1];[4;4];[0;0;399]]

用makeIndex测试l ;;

决定我真正想要的是什么
let cmpSnd' (a,(xs: int list))  = Seq.sum  xs;;
let maxIndex' seq=fst (Seq.maxBy cmpSnd' (zipIndex seq));;

现在是时候分解并使makeIndex成为一个函数

let maxIndexF seq maxF=fst (Seq.maxBy maxF (zipIndex seq));;

val l : int list list = [[1; 2; 199]; [3; 3]; [4; 1]; [0; 299]]

> maxIndexF l cmpSnd'
;;
val it : int = 3
> maxIndexF l cmpSnd
;;
val it : int = 2

完成它

let maxIndexF'  maxF=fst << Seq.maxBy maxF << zipIndex ;;

maxIndexF' cmpSnd' l;;
maxIndexF' cmpSnd l;;