Seq.max
finds the max number. I'd like to have something like Seq.findIndex
Seq.maxIndex
returns the index of the maximum element.
Seq.max
finds the max number. I'd like to have something like Seq.findIndex
Seq.maxIndex
returns the index of the maximum element.
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 http://stackoverflow.com/questions/1496980/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;;
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
)