F#交错两个列表

4
有没有一种方法可以合并两个列表?
let a = ["a"; "b"; "c"]
let b = ["d"; "b"; "a"]

所以我得到了这个结果。
result = ["a"; "d"; "b"; "b"; "c"; "a"]

1
你是在尝试自己找到解决方案吗? - FoggyFinder
3个回答

8
这个任务最好使用 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"]

6

一个快速而不太优雅的解决方案是将这两个列表压缩成一个,然后展开结果元组:

let interleave a b =
    List.zip a b |> List.collect (fun (a,b)-> [a;b])

这会返回一个交错元素的列表:

interleave a b;;
val it : string list = ["a"; "d"; "b"; "b"; "c"; "a"]

zip 会从两个列表的元素中创建成对:

val it : (string * string) list = [("a", "d"); ("b", "b"); ("c", "a")]

collect会将元组压缩


3
为了补充@Panagiotis Kanavos的标准库答案,这里提供一个手动实现的方法,它应该会占用更少的内存,因为它不会构建元组(但仍需要一个中间列表):
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

(这个链接中的解决方案不是尾递归,因此也不够优化)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接