2016-09-29 142 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