Reputation: 1445
I have a following problem. From a list, I must separate mod 3 = 0 element, mod 3 = 1 element and mod 3 = 2 element to 3 different lists and return list of these 3 lists. My question is pretty obvious - how do I do that? Is there some kind of simple rule to this I'm missing?
What I have so far is not much but there you go:
let separate xs =
let rec help xs i =
match xs i with
| [] _ -> []
| hd a -> if a mod 3 = 0 //HOW DO I RETURN
else if a mod 3 = 1
else
UPDATED: Finished code:
let separate xs =
let rec help (list, i, xs1, xs2, xs3) =
match list with
| [] -> [xs1;xs2;xs3]
| head :: tail -> (if i mod 3 = 0 then help (tail, i+1, head::xs1, xs2, xs3)
else if i mod 3 = 1 then help (tail, i+1, xs1, head::xs2, xs3)
else help (tail, i+1, xs1, xs2, head::xs3))
in help (xs, 0, [], [], []);;
Upvotes: 1
Views: 955
Reputation: 35210
A usual way is to use List.fold*
function, that generalizes an idea of list iteration. But, in your case, it may not be appropriate (depending on what your teachers are asking).
You can iterate over your list maintaining some notion of state (indeed, you need three extra "variables" for three different lists). Here is a pattern for iterating over lists
let my_function lst =
let rec loop acc lst = match lst with
| [] -> <do_some_post_iteration_work> acc
| head :: rest ->
let result = <do_something_with_nth_element> head in
let accum = <add_result_to_accumulator> result acc in
loop accum rest in
let accum = <initialize_accumulator> in
loop accum lst
I used long names so that you can understand the meaning without extra comments, although you're welcome to ask. Also, keep in mind, that your state (aka accumulator), can be also a value of any type. Using a triple would be a not a bad idea in your case.
Upvotes: 1
Reputation: 24812
You'll need to accumulate the partial results in lists, and then return those lists :
let split_by_mod_3 l =
let rec aux l mod0 mod1 mod2 = match l with
| [] -> [mod0; mod1; mod2]
| hd::tail when hd mod 3 == 0 -> aux tail (hd::mod0) mod1 mod2
| hd::tail when hd mod 3 == 1 -> aux tail mod0 (hd::mod1) mod2
| hd::tail when hd mod 3 == 2 -> aux tail mod0 mod1 (hd::mod2)
in
aux l [] [] [];;
Upvotes: 2