OCaml - 如何从列表中返回列表列表?

时间:2014-10-27 10:54:11

标签: list ocaml

我有以下问题。从列表中,我必须将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, [], [], []);;

2 个答案:

答案 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

我使用了很长的名字,这样你就可以在没有额外评论的情况下理解其含义,尽管欢迎你提出要求。另外,请记住,您的状态(也称累加器)也可以是任何类型的值。在你的情况下,使用三元组并不是一个坏主意。