最小/最大和列表中最常见的元素

Sim*_*ari 6 f#

我必须编写一个程序,在输出中输入一个元组:非空列表的最小值和最大值以及最常出现的值.特别是:

min_max [1;0;-1;2;0;-4] ==> (-4; 2)
min_max: int list -> (int * int)

mode [-1;2;1;2;5;-1;5;5;2] ==> 2
mode: int list -> int
Run Code Online (Sandbox Code Playgroud)

这是我为max编写的代码(min几乎相等)但是如何使用这两个值作为输出接收元组?

let rec max_list xs =
    match xs with
    | [] -> failwith "xs" "Empty list"
    | [x] -> x
    | x1::x2::xs' -> max_list((max2 x1 x2)::xs');;
Run Code Online (Sandbox Code Playgroud)

kae*_*fer 5

我将采用@Mark Seemann的答案中的第一个建议并运行它,以便使其通用,适用于任何集合类型,并明智地处理空集合的情况。

let tryMinMax xs =
    Seq.fold (function
    | Some(mn, mx) -> fun i -> Some(min mn i, max mx i)
    | None         -> fun i -> Some(i, i) ) None xs

[1;0;-1;2;0;-4]
|> tryMinMax
// val it : (int * int) option = Some (-4, 2)
Run Code Online (Sandbox Code Playgroud)

对于问题中最常见的部分:

let mostFrequent xs =
    xs 
    |> Seq.countBy id 
    |> Seq.maxBy snd
    |> fst

[1;0;-1;2;0;-4]
|> mostFrequent
// val it : int = 0
Run Code Online (Sandbox Code Playgroud)


Mar*_*ann 2

let minMax xs =
    xs
    |> List.fold
        (fun (mn, mx) i -> min mn i, max mx i)
        (System.Int32.MaxValue, System.Int32.MinValue)
Run Code Online (Sandbox Code Playgroud)

效率不是特别高,但是写起来很有趣:

let mode xs =
    xs
    |> List.groupBy id
    |> List.map (fun (i, is) -> i, Seq.length is)
    |> List.maxBy snd
    |> fst
Run Code Online (Sandbox Code Playgroud)