How to find max's index in a Seq, List or Array in F#
Seq.max
finds the max number. I'd like to have something like开发者_高级运维 Seq.findIndex
Seq.maxIndex
returns the index of the maximum element.
I believe you are looking for something like:
let maxIndex seq =
fst (Seq.maxBy snd (Seq.mapi (fun i x -> i, x) seq))
Note that giving this function an empty sequence will result in an ArgumentException.
(Alternatively, written in pipelining style:
let maxIndex seq =
seq
|> Seq.mapi (fun i x -> i, x)
|> Seq.maxBy snd
|> fst
)
Why not simply use
let l=[1;2;5;3];;
Seq.findIndex (fun x -> x= Seq.max l) l ;;
?
Or maybe as Johan Kullbom suggest in a comment:
"let m = Seq.max l in Seq.findIndex (fun x -> x = m) l"
if you what a little better O(n)
However, the need to get the index looks to me like a imperative "code smell" .
In FP it's usually better to use existing functions before you roll your own. I now this in the eyes of a C programmer seems like a for(i (for(j construct but I bet that you probably really don't need to know the index if you start think in FP.
More or less a duplicate of Finding index of element in a list in Haskell?
PS. I can't resist. In Haskell (ghc) the way should probably be something like
let cmpSnd (_, y1) (_, y2) = compare y1 y2
let maxIndex l= fst $ maximumBy cmpSnd $ zip [0..] l
However, since zip in F# doesn't seem to allow zip with unequal lengths of the list(?) the use of mapi is probably the way to go (my haskell version in F#)
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));;
and the reason is only so that I can make a list
let l= [[0;199;1];[4;4];[0;0;399]]
test with makeIndex l;; and decide that what I really want is a
let cmpSnd' (a,(xs: int list)) = Seq.sum xs;;
let maxIndex' seq=fst (Seq.maxBy cmpSnd' (zipIndex seq));;
Now time to decomposite and make makeIndex take a function
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
Finish it up
let maxIndexF' maxF=fst << Seq.maxBy maxF << zipIndex ;;
maxIndexF' cmpSnd' l;;
maxIndexF' cmpSnd l;;
精彩评论