2017-06-05 73 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