F# - splitting list of integers into odds and evens using List.foldBack

Viewed 311

I'm trying to write a function using List.foldBack that'll split a list of integers into a tuple containing two lists: One containing the odds and the other the evens of the original list. Example:

Given the list myList = [1;4;2;6;5;3;10], the function should return the tuple ([4;2;6;10], [1;5;3]).

I have found plenty of solutions for splitting lists into sublists by their indices, however as explained I need to split the list by element value, not index.

So I figured I would write a function using List.foldBack that would split by index and then rewrite it to split by value, but have yet to be successful ... here is what I've arrived at so far:

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

As you might've guessed, running myList through my function returns ([1;2;5;10], [4;6;3]).

I am restricted to using List.-fold, foldBack, find, filter, map, and map2, but would prefer to see a solution using only foldBack, if possible.

1 Answers

Your code doesn't actually check whether the value is odd or even – it just adds it to the 'odds' list regardless, and swaps the 'odds' and 'evens' lists for each value. Fixing both is straightforward, if ugly:

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

How to make things less ugly is subjective, but here are a couple of options:

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

Personally, I recommend the latter as it plays better with type inference in general (it made no difference here since int could be inferred regardless due to use of %).

Related