List F#-将列表拆分为奇偶列表的元组(按元素,而不是位置)

List F#-将列表拆分为奇偶列表的元组(按元素,而不是位置),list,recursion,split,f#,partition,List,Recursion,Split,F#,Partition,示例:split[1;3;2;4;7;9] 输出:([1;3;7;9],[2;4]) 我对F#还不熟悉,我搞不懂。 无法使用分区内置函数 这就是我到目前为止所做的: let rec split xs = match xs with | [] -> [], [] | xs -> xs, [] | xh::xt -> let odds, evens = split xt if (xh % 2) = 0 then xh

示例:
split[1;3;2;4;7;9]
输出:
([1;3;7;9],[2;4])

我对F#还不熟悉,我搞不懂。
无法使用
分区
内置函数

这就是我到目前为止所做的:

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

*感谢@TheInerlight指出我的错误:无法到达的情况和不必要的修改赔率

您可以使用内置的
列表.分区
功能

let splitOddEven xs =
    xs |> List.partition (fun x -> x % 2 <> 0)
如果您想要递归实现,我可能会选择这样的尾部递归实现:

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]

请注意,这将以相反的顺序显示两个结果列表,因此您可能希望自己将其反转。

这正是我想要的。但是我不能使用List.partition函数来解决这个问题。我将研究这个函数是如何工作的,并试图解决这个问题。非常感谢@SergiorRosales还添加了一个递归实现。@SergiorRosales没问题。仅供参考,您在问题中提供的实现几乎可以正常工作。如果您删除
|xs->xs,[]
模式匹配案例,并将
If(xh%2)=0替换为
If(xh::赔率,xh::evens
,那么您就有了另一个工作实现。不过,这种实现不是尾部递归的,因为进行递归调用并不是函数最后要做的事情。这就是为什么我想向你们展示一些不同的东西。有一个建议,因为这似乎是家庭作业:你们应该告诉你们的教授,你们要求帮助解决堆栈溢出问题,以及你们得到了什么帮助。最好的方法是包含一个指向此问题的链接--
https://stackoverflow.com/q/44379239/
——当你交作业时,在作业的注释中。根据你教授关于寻求帮助的政策,你可能需要也可能不需要这样做,但是完全披露你在做家庭作业时得到的任何帮助总是一个好主意。感谢你编辑这个问题,以帮助将来可能找到它的其他人。然而,在堆栈溢出时,没有必要在问题的标题中加上“(已解决)”:您通过给答案打绿色复选标记来接受答案的事实足以传达这一事实,事实上,人们不喜欢在问题标题中加上“(已解决)”。不过,我们非常感谢您愿意这样做。:-)
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]