F#删除重复项

时间:2016-09-29 15:16:33

标签: list recursion f#

我正在尝试使用此功能删除列表中的重复项。它删除重复项,但以相反的顺序返回列表。我有点不确定如何在没有丑陋的解决方案的情况下解决这个问题。

3 个答案:

答案 0 :(得分:3)

已经有其他答案显示了各种实用的解决方案,但我想您对使代码工作的最小变化感兴趣。在函数式编程中使用累加器时,通常最终会反转列表 - 标准的解决方案是在最后反转列表,您可以使用List.rev执行此操作:

let rd list= 
   let rec func list nlist=
      match list with
      | [] -> List.rev nlist // Reverse the list before returning it
      | x::xs ->
         if not (isMember x nlist) then 
            func xs (x::nlist)
         else
            func xs nlist
   func list []

除了添加List.rev之外,我还将最后一行更改为func list [](您的代码在那里有add,但这可能是一个错字)。我还将isMember x nlist <> true更改为更惯用的not (isMember x nlist)

答案 1 :(得分:2)

您可以执行此操作以删除重复项:

Seq.distinct [1;1;2;4;4;5;6]

返回[1; 2; 4; 5; 6]

答案 2 :(得分:1)

我不太清楚你需要从解决方案中的标准库函数中获得多少帮助(或缺少它)。

最简单的方法就是使用List.distinct

List.distinct [1;1;2;4;4;5;6];;
val it : int list = [1; 2; 4; 5; 6]

您可以使用foldBack

制作版本
let distinct lst = 
    List.foldBack (fun v lst' -> 
        if List.contains v lst' then lst'
        else v::lst') lst []

这会产生相同的结果:

distinct [1;1;2;4;4;5;6];;
val it : int list = [1; 2; 4; 5; 6]

如果你想创建自己的foldBack ......

let rec foldBack f lst z =
    match lst with
    |[] -> z
    |x::xs -> f x (foldBack f xs z)

请注意,我尝试不编写一个可以完成所有操作的大型函数,而是尝试使用一系列可重用的组件构建解决方案 - 这是在使用函数式语言时进入的一个好习惯。 / p>