我们可以创建从列表中获取 n 个元素并从列表中删除 n 个元素的函数,如下所示:
let rec take n l =
if n = 0 then
[]
else
match l with
h::t -> h :: take (n - 1) t
同样,
let rec drop n l =
if n = 0 then
l
else
match l with
h::t -> drop (n - 1) t
但是我们如何组合 take 和 drop 函数,使其返回一个对,其结果是从列表中删除 n 个元素并添加 n 个元素
l
?
这也可以在 ocaml-containers 中使用,如
take_drop
:
val take_drop : int -> 'a t -> 'a t * 'a t
在简街的基地为
split_n
val split_n : 'a t -> int -> 'a t * 'a t
我会使用尾递归方法,并使用辅助函数在额外参数中构建前 N 个元素(最初按相反顺序),然后在返回列表之前反转该列表。这样无论 N 有多大,它都占用相同的堆栈空间。
let split n lst =
let rec helper n lst head =
if n = 0 then
head, lst
else
match lst with
| car :: cdr -> helper (n - 1) cdr (car :: head)
| [] -> head, [] (* List is shorter than n *) in
let head, tail = helper n lst [] in
List.rev head, tail
let rec add_drop n l =
if n = 0 then
([], l)
else
match l with
h::t ->
let (a, b) = add_drop (n - 1) t in
(h::a, b)