2017-10-07 44 views
2

我試圖用List.foldBack編寫一個函數,它將一個整數列表分成一個包含兩個列表的元組:一個包含可能性,另一個包含可能性原始列表的列表。例如:F# - 使用List.foldBack將整數分割爲機率和平均值

鑑於列表myList = [1;4;2;6;5;3;10],函數應返回元組([4;2;6;10], [1;5;3])

我發現很多解決方案通過它們的索引將列表拆分成子列表,然而正如我所解釋的,我需要按列表元素值而不是索引拆分列表。

所以我想我會寫使用List.foldBack功能,將通過索引拆分,然後重寫它的價值分裂,但還沒有成功......這裏是我在迄今爲止到達:

let oddEvenSplit (listToSplit:int list) = 
    List.foldBack (fun x (even, odd) -> x::odd, even) listToSplit ([], []) 

正如您可能已經猜到的,通過我的函數運行myList返回([1;2;5;10], [4;6;3])

我只能使用List. - foldfoldBackfindfiltermapmap2,但我們更希望看到只用foldBack的解決方案,如果可能的話。

回答

3

你的代碼實際上並不檢查這個值是奇數還是偶數 - 它只是將它添加到'賠率'列表中,並且爲每個值交換'賠率'和'evens'列表。固定兩個很簡單,如果醜:

let oddEvenSplit listToSplit = 
    List.foldBack 
     (fun x (even, odd) -> if x % 2 = 0 then (x::even, odd) else (even, x::odd)) 
     listToSplit 
     ([], []) 

如何使事情少醜是主觀的,但這裏有幾個選項:

let oddEvenSplit listToSplit = 
    let impl x (even, odd) = if x % 2 = 0 then (x::even, odd) else (even, x::odd) 
    List.foldBack impl listToSplit ([], []) 

// or 

let oddEvenSplit listToSplit = 
    (listToSplit, ([], [])) ||> List.foldBack (fun x (even, odd) -> 
     if x % 2 = 0 then (x::even, odd) else (even, x::odd)) 

我個人推薦後者,因爲它起到更好一般的類型推斷(這裏沒有差別,因爲int可以推斷,不管是因爲使用%)。

+1

非常感謝你!我認爲第一個解決方案根本不好看。但也許這是因爲F#對我來說還是很新的,這是你提出的三種解決方案中最適合我當前對語言理解的解決方案之一。非常感激!! –