Is there a way that I could merge 2 lists
let a = ["a"; "b"; "c"]
let b = ["d"; "b"; "a"]
so I get this result
result = ["a"; "d"; "b"; "b"; "c"; "a"]
This task is best solved by foldBack2
:
let al = ["a"; "b"; "c"]
let bl = ["d"; "b"; "a"]
List.foldBack2 (fun a b xs -> a :: b :: xs) al bl []
// ["a"; "d"; "b"; "b"; "c"; "a"]
A quick & dirty solution would be to zip the two list, then flatten the resulting tuples:
let interleave a b =
List.zip a b |> List.collect (fun (a,b)-> [a;b])
This returns a list with the interleaved elements:
interleave a b;;
val it : string list = ["a"; "d"; "b"; "b"; "c"; "a"]
zip
will create pairs from the elements of both lists :
val it : (string * string) list = [("a", "d"); ("b", "b"); ("c", "a")]
and collect
will flatten the tuples
To complement @Panagiotis Kanavos's standard library-based answer, here's a hand implementation which should consume slightly less memory because it doesn't build tuples (but still requires an intermediate list):
let interleave a b =
let rec loop acc a b =
match a, b with
| [], l | l, [] -> List.rev l @ acc
// Or if you want to fail when the lengths are different, replace the above with:
// | [], [] -> acc
// | [], _ | _, [] -> failwith "interleave: List lengths are different"
| a :: aa, b :: bb -> loop (b :: a :: acc) aa bb
loop [] a b |> List.rev
(The solutions in this link are not tail-recursive, so sub-optimal too)