4

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"]
Mark
  • 1,633
  • 1
  • 11
  • 26

3 Answers3

8

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"]
David Raab
  • 4,433
  • 22
  • 40
6

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

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
3

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)

Community
  • 1
  • 1
Tarmil
  • 11,177
  • 30
  • 35