2010-01-10 55 views

回答

12

我相信你正在寻找例如:

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 

3

为什么不能简单地用

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

或者,也许是约翰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#似乎并没有让拉链与不同长度的列表(?)使用mapi可能是要走的路(我的哈克尔l在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));; 

,原因是只有这样我可以做一个列表与makeIndex升

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

测试;; 并决定我真正想要的是一个

let cmpSnd' (a,(xs: int list)) = Seq.sum xs;; 
let maxIndex' seq=fst (Seq.maxBy cmpSnd' (zipIndex seq));; 

现在时间decomposite并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;; 
+2

该解决方案将遍历序列很多次(最坏情况N * N次)。 “让seq.findIndex(fun x - > x = m)l”中的m = Seq.max l将至少仅遍历序列两次... – 2010-01-10 14:39:09

+0

是的(那里的参考为(我为(j),但风格(在你的答案中给出)似乎表明你应该使用索引,并且如果你正在学习FP并且不仅仅试图重新编码你的命令我知道我可能会更多地阅读这个问题,而不是编译和回答它 – Jonke 2010-01-10 15:20:57

+0

我相信你是对的 - 因为索引可能不需要在第一个地方...... :) – 2010-01-10 16:03:50