简体   繁体   中英

F# - splitting list into tuple of odd-even lists (by element, not position)

Example: split [1;3;2;4;7;9];;
Output: ([1;3;7;9], [2;4])

I'm new to F# and I can't figure it out.
Can't use the partition built in function.

This is what I have so far:

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  

Fixed code:

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

*Thanks to @TheInnerLight for pointing out my errors: unreachable case and unnecessarily modifying odds

You can use the built-in List.partition function

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]) 

If you want a recursive implementation, I'd probably go for a tail recursive implementation like this:

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]

Note that this will give you the two resulting lists in reverse order so you might wish to reverse them yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM