2016-09-29 100 views
3

我试图用此功能删除列表中的重复项。它删除重复项,但以相反顺序返回列表。我有点不确定如何解决这个问题,而不是一个丑陋的解决方案。F#删除重复

+3

使用'foldback'? –

+0

不知道那是什么。 – alexanderson

+1

'removeDuplicates'中的内部lambda应该被命名为'func'或'add',但沿代码保持不变;那就是说,你只需要使用'List.rev'或者写你自己的方法来反转结果列表。 – Sehnsucht

回答

2

为此,您可以删除重复:

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

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

+0

这不是真正的即时通讯练习。“< – alexanderson

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) 

注意到,我尽量不写一个大功能,做一切和我,而不是试图建立从一个解决方案一系列可重用组件 - 这是在使用功能语言时进入的好习惯。

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

可以更加习惯于颠倒'if'和'else'块并放下'not' – Sehnsucht