My goal here is to have a split n l
function that takes a N
and a list as argument and try to split that list into N
number of equal sized lists.
The signature of my function would be: val split : int -> 'a list -> 'a list list = <fun>
The execution on that list: [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20]
would give, for example:
[[0; 1; 2; 3; 4; 5; 6]; [7; 8; 9; 10; 11; 12; 13]; [14; 15; 16; 17; 18; 19; 20]];
I have tried to inspire myself with an OCaml book I'm working with and functions I've found such as
let take l n =
if n < 0 then
raise (Invalid_argument "take")
else
let rec take_inner r l n =
if n = 0 then
List.rev r
else
match l with
| [] -> raise (Invalid_argument "take")
| h :: t -> take_inner (h :: r) t (n - 1) in
take_inner [] l n
let drop l n =
let rec drop_inner n l =
match l with
| [] -> raise (Invalid_argument "drop")
| _ :: t ->
if n = 1 then
t
else
drop_inner (n - 1) t in
if n < 0 then
raise (Invalid_argument "drop")
else if n = 0 then
l
else
drop_inner n l
let rec split n l =
try take l n :: split n (drop l n)
with _ -> (
match l with
| [] -> []
| _ -> [l])
I feel like I'm close to what I'd like to achieve even though this version gives a list of N sized sublists, and not N sublists.
I just don't see how to tweak everything together to get to what I want.
Any advices please? Thanks.
CodePudding user response:
If you want to split the initial list into n
equally sized lists, then you first need to determine the size of each list. For that, you need to compute the size of the original list and divide it by n
. If it divides evenly, then this is the length of each list, and you already know how to generate lists of the given length. If it doesn't divide evenly, then you can either generate an error or leave the last list shorter, depending on what you want from your function.