2017-06-05 56 views
3

例子:split [1;3;2;4;7;9];;
輸出:([1;3;7;9], [2;4])F# - 分裂列表分爲奇偶列出的元組(由元素,而不是位置)

我是新來的F#,我無法弄清楚。
不能使用內置函數partition

這是我到目前爲止有:

let rec split xs = 
    match xs with 
    | [] -> [], [] 
    | xs -> xs, [] 
    | xh::xt -> let odds, evens = split xt 
       if (xh % 2) = 0 then xh::odds, xh::evens 
       else xh::odds, evens 

固定碼:

let rec split xs = 
    match xs with 
    | [] -> [], [] 
    | xh::xt -> let odds, evens = split xt 
       if (xh % 2) = 0 then odds, xh::evens 
       else xh::odds, evens 

*感謝@TheInnerLight指出我的錯誤:無法訪問的情況和不必要的修改賠率

+1

一個建議的詞,因爲這似乎是作業:你應該告訴你的教授,你要求在堆棧溢出的幫助,以及你得到的幫助。做到這一點的最佳方法是在你的作業的評論中包含一個指向這個問題的鏈接 - 'https:// stackoverflow.com/q/44379239 /' - 根據你的教授的政策在尋求幫助時,您可能會也可能不需要這樣做,但完全披露您在做家庭作業時獲得的任何幫助總是一個好主意。 – rmunn

+0

感謝您編輯此問題以幫助其他將來可能找到它的人。然而,在Stack Overflow中,不需要在問題標題中加入「(已解決)」:您已通過給它一個綠色複選標記來接受答案,這足以說明這一事實,實際上人們更喜歡* not *有「(已解決)」提出問題標題。不過,你願意這樣做是值得讚賞的。 :-) – rmunn

回答

8

您可以使用內置的List.partition功能

let splitOddEven xs = 
    xs |> List.partition (fun x -> x % 2 <> 0) 
splitOddEven [1;3;2;4;7;9];; 
val it : int list * int list = ([1; 3; 7; 9], [2; 4]) 

如果你想要一個遞歸實現,我可能會去一個尾遞歸實現這樣的:

let splitOddEven xs = 
    let rec splitOddEvenRec oddAcc evenAcc xs = 
     match xs with 
     | [] -> oddAcc, evenAcc 
     | xh::xt -> 
      if (xh % 2) = 0 then splitOddEvenRec oddAcc (xh :: evenAcc) xt 
      else splitOddEvenRec (xh :: oddAcc) evenAcc xt 
    splitOddEvenRec [] [] xs 

splitOddEven [1;3;2;4;7;9] 

注意,這會給你反兩個結果列表所以你可能希望自己改變它們。

+0

這正是我想要的。但是我不能使用List.partition函數來解決這個問題。我將研究該功能如何工作並嘗試解決該問題。非常感謝! –

+0

@SergioRosales剛剛添加了遞歸實現。 – TheInnerLight

+0

@SergioRosales沒問題。僅供參考,您在問題*中提供的實現幾乎可行。如果你刪除'| xs - > xs,[]'模式匹配大小寫,並用if if(xh%2)= 0替換if(xh%2)= 0,然後xh :: odds,xh :: evens'然後賠率,xh :: evens ',你有另一個工作實現。該實現不是尾遞歸,但因爲遞歸調用並不是函數的最後一件事。這就是爲什麼我想告訴你一些不同的東西。 – TheInnerLight