I'd like to write a function in OCaml, using only recursivity that can transform any list of list that look like: [[a1;...;an];[b1;...bn];...;[z1;...;zn]]
into [[a1;b1;...;z1];...;[an;...;zn]]
what I've done so far is quite complex, I insert element by element reconstructing a new list every time ... and I'm sure there is a simpler way ...
My code so far:
let inserer l e i =
let rec aux l e i j =
match l with
| [] -> failwith "erreur position inexistante"
| t::q when j = i ->
if List.length t = 0 then
[e]::q
else
let t1 = List.hd t in
let q1 = List.tl t in
let l1 = t1::e::q1 in
l1::q
| t::q -> t::(aux q e i (j 1))
in
aux l e i 0
let inserer_liste b m =
let rec aux b m i =
match b with
| [] -> m
| t::q ->
let tmp = inserer m t i in
aux q tmp (i 1)
in
aux b m 0
let transform u n =
let rec aux u m =
match u with
| []-> m
| b::q ->
let tmp = inserer_liste b m in
aux q tmp
in
aux u (List.init n (fun _ -> []))
let u = [[1;2;3]; [4;5;6]; [7;8;9]]
let l = transform u 3
CodePudding user response:
I have a feeling that this transformation is way more natural if you transform an array of lists into a lists of arrays. You can transform into a list of lists afterwards.
let rec f a =
match a.(0) with
| [] -> []
| _ :: _ ->
let hd = Array.map List.hd a in
for i = 0 to Array.length a - 1 do
a.(i) <- List.tl a.(i)
done ;
hd :: (f a)
This consumes the input array, which can be solved by shadowing f
in the following way :
let f a = f (Array.copy a)
let f_list l = List.map Array.to_list (f (Array.of_list l))
You could also reallocate a new array at each recursive call, but that would be slower, without any upside except maybe a bit nicer code.
f_list
is more elegant this way :
let f_list l =
l |> Array.of_list |> f |> List.map Array.to_list
There is no error handling in my code : it assumes all list have the same length, but it should be to hard to add it.
CodePudding user response:
Is there a simple way... Not that I know of but that doesn't say much.
Here's something I tried.
let lol =
[
[ 1; 2; 3; 4; ];
[ 5; 6; 7; 8; ];
[ 9; 10; 11; 12; ];
]
let ans =
List.fold_left
(
fun a e ->
match a with
| [] -> List.fold_right (fun e a -> [e]::a) e a
| _ -> List.fold_right2 (fun b c acc -> (c @ [b])::acc) e a []
)
[]
lol
let () =
List.iter
(
fun l ->
List.iter (fun x -> Printf.printf "%d " x) l;
print_newline()
)
ans