我有一个序列,我需要找到序列的最小值,以及序列中该值的索引 - 实际上是Seq.mapi或Seq.iteri行中的某种“Seq.mini”函数。
在F#中表达这种最干净/最恰当的方法是什么?
惯用法,我是否应该期望编写一个返回元组(值,索引)或(索引,值)的函数,如果有的话,是否存在这些值应出现在哪个顺序的约定?
另一件事:如果有多个元素具有相同的最小值,我需要第一次出现的索引 - 我想这会转换为严格的“小于(<)”比较而不是“小于”或等于(< =)“ - 正确吗?
答案 0 :(得分:5)
这是一个简单的清洁解决方案:
let mini s = s |> Seq.mapi (fun i x -> (i, x)) |> Seq.minBy snd
let index, value = seq [3;6;1;5;1] |> mini
答案 1 :(得分:1)
我会考虑更多,并定义两个通常有用的函数。
(* Infinite sequence of whole numbers. 0 .. *)
let indices = Seq.unfold (fun x -> Some(x, x + 1)) 0
(* Zips the given sequence with indices of elements. *)
let zipWithIndex coll = Seq.zip coll indices
printfn "%A" ([12; 8; 9; 90; 3; 24] |> zipWithIndex |> Seq.minBy fst) // prints (3, 4)
答案 2 :(得分:0)
这个怎么样
let tuple a b = a, b
let uncurry f (a, b) = f a b
module Seq =
let inline miniBy f seq =
(Seq.mapi tuple
>> Seq.minBy (uncurry f)) seq
Seq.miniBy (fun i x -> x) [ 4; 6; 3; 7; 2; 2; 7 ]
谓词函数接收索引,但在这种情况下不需要使用它。
注意: miniBy : (int -> 'a -> 'b) -> seq<'a> -> int * 'a when 'b : comparison