如何重塑列表

问题描述 投票:0回答:2

所以考虑获取一个

[1; 2; 3; 4; 5; 6; 7; 8; 9]
的列表并将其重塑为
[[1; 2; 3]; [4; 5; 6]; [7; 8; 9]]
。你会如何在 OCaml 中做到这一点?我想要一个简单的函数或标准库中的东西。

list ocaml
2个回答
0
投票

事实证明,考虑到列表的长度可以被 3 整除,只需 3 行代码就可以轻松完成。

let rec re_shape = function
| x :: xs :: xz :: xt -> [x; xs; xz] :: re_shape xt
| _ -> []

这是如何工作的,对于每次迭代,它都包含一个 3 列表到函数的其余部分,直到它到达结尾。添加最后一行是为了安全。


0
投票

正如您所展示的解决此问题的努力,为了您的考虑,请参阅下面的a策略以将其概括为允许任何长度。

partition
函数将允许我们从列表中获取前
n
元素和其余元素,如果列表中没有
Invalid_argument
元素,则提高
n

chunks
函数递归地将此应用于余数以构建列表列表。

let partition n lst =
  let rec partition' n (first, rest) =
    match n, rest with  
    | 0, _ -> (List.rev first, rest)
    | _, [] -> invalid_arg "List not long enough"
    | _, x::xs -> partition' (n-1) (x :: first, xs)
  in
  partition' n ([], lst)
  
let rec chunks n lst =
  match partition n lst with  
  | first, [] -> [first]
  | first, rest -> first :: chunks n rest
  | exception (Invalid_argument _) ->
    invalid_arg @@ Format.sprintf "List length not evenly divisible by %d" n

第二个函数是 not 尾递归的,尽管这可以很容易地在 OCaml 4.14 和更高版本中解决:

let[@tail_mod_cons] rec chunks n lst =
  ...
© www.soinside.com 2019 - 2024. All rights reserved.