我有以下问题。从列表中,我必须将mod 3 = 0元素,mod 3 = 1元素和mod 3 = 2元素分成3个不同的列表,并返回这3个列表的列表。我的问题非常明显 - 我该怎么做?我缺少某种简单的规则吗?
到目前为止我所拥有的并不多,但你去了:
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
更新: 完成的代码:
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, [], [], []);;
答案 0 :(得分:2)
您需要在列表中累积部分结果,然后返回这些列表:
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 [] [] [];;
答案 1 :(得分:1)
通常的方法是使用List.fold*
函数,它概括了列表迭代的概念。但是,在您的情况下,它可能不合适(取决于您老师的要求)。
你可以迭代你的列表,保持一些状态概念(实际上,你需要三个额外的"变量"三个不同的列表)。这是迭代列表的模式
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
我使用了很长的名字,这样你就可以在没有额外评论的情况下理解其含义,尽管欢迎你提出要求。另外,请记住,您的状态(也称累加器)也可以是任何类型的值。在你的情况下,使用三元组并不是一个坏主意。