比较循环内部函数的值

时间:2013-11-26 14:09:50

标签: f# inline c#-to-f#

我想创建一个以整数列表作为参数的函数,并比较每个值并返回最大值。在C#中,我只是遍历列表中的每个值,将最大值保存到变量并返回它,我希望F#的工作方式类似,但语法对我来说有点不合适,这就是我的代码的样子。此外,max2是一个比较2个值并返回最大值的函数。

let max_list list = 
    let a = 0 : int
    match list with
    | head :: tail -> (for i in list do a = max2 i a) a
    | [] -> failwith "sry";; 

3 个答案:

答案 0 :(得分:12)

您可以使用mutable变量并使用for循环编写代码,就像在C#中一样。但是,如果你这样做是为了学习F#和功能概念,那么使用递归是个好主意。

在这种情况下,递归函数有点长,但它演示了包括模式匹配在内的关键概念 - 因此在编写更复杂的F#代码时学习技巧会很有用。

关键的想法是编写一个函数,该函数采用到目前为止找到的最大值,并递归调用自身直到它到达列表的末尾。

let max_list list = 
  // Inner recursive function that takes the largest value found so far
  // and a list to be processed (if it is empty, it returns 'maxSoFar')
  let rec loop maxSoFar list = 
    match list with
    // If the head value is greater than what we found so far, use it as new greater
    | head::tail when head > maxSoFar -> loop head tail
    // If the head is smaller, use the previous maxSoFar value
    | _::tail -> loop maxSoFar tail
    // At the end, just return the largest value found so far
    | [] -> maxSoFar
  // Start with head as the greatest and tail as the rest to be processed
  // (fails for empty list - but you could match here to give better error)
  loop (List.head list) (List.tail list)

作为最后一点,这将是缓慢的,因为它使用通用比较(通过接口)。您可以使用let inline max_list list = (...)更快地完成此功能。这样,当与int这样的原始类型一起使用时,代码将使用本机比较指令(这实际上是一个特殊情况 - 问题只发生在通用比较中)

答案 1 :(得分:3)

还要知道你可以使用reduce编写一个漂亮的单行代码:

let max_list list = List.reduce (fun max x -> if x > max then x else max)

答案 2 :(得分:0)

如果您的目的是能够找到列表中项目的最大值,其中函数max2找到了项目的值,则此方法有效:

let findMax list =
   list 
   |> List.map (fun i -> i, max2 i)  
   |> List.maxBy snd
   |> fst