合并2个序列

时间:2019-05-05 08:19:39

标签: .net functional-programming f#

我正在尝试重新创建自己的Seq.zip函数。 它需要执行与Seq.zip完全相同的操作,但只需要使用seq即可创建它。到目前为止,这是我的代码:

let rec seqZip s1 s2 =
    seq {
        let e1 = Seq.item 0 s1
        let e2 = Seq.item 0 s2

        let rec helper s1 s2 n =
            match s1, s2 with
            | s1, s2 when n > s1.Length && n > s2.Length -> yield ()
            | s1, s2 -> yield (Seq.item (n+1) s1, Seq.item (n+1) s2)

        helper s1 s2 0
    } 

我不确定那里是否需要帮助功能,但是您有什么建议吗?

2 个答案:

答案 0 :(得分:6)

类型声明System.Collections.Generic.IEnumerable<'a>MoveNext()的类型别名。该接口提供了一个枚举器,我们可以使用它遍历集合,所有更高级别的函数也将依赖于这些接口。因此,使用Current方法和let zip (s1 : seq<_>) (s2 : seq<_>) = use e1 = s1.GetEnumerator() use e2 = s2.GetEnumerator() let rec loop () = seq{ if e1.MoveNext() && e2.MoveNext() then yield e1.Current, e2.Current yield! loop() } loop() zip [1..3] [11..14] |> Seq.toList // val it : (int * int) list = [(1, 11); (2, 12); (3, 13)] Seq.zip [1..3] [11..14] |> Seq.toList // val it : (int * int) list = [(1, 11); (2, 12); (3, 13)] 属性迭代序列应该是最有效的方法。

=IMPORTDATA("https://drive.google.com/uc?export=download&id=KEY_DRIVE_FILE")

嵌套的辅助函数很好地封装了递归。

答案 1 :(得分:0)

更面向序列的解决方案是:

let rec seqzip (a: 'a seq) (b: 'b seq): ('a*'b) seq =
    match a with
    | empty when Seq.isEmpty empty -> Seq.empty<'a*'b>
    | aa ->
        match b with
        | empty when Seq.isEmpty empty -> Seq.empty<'a*'b>
        | bb -> seq{
            yield (Seq.head aa, Seq.head bb)
            yield! (seqzip (Seq.tail aa) (Seq.tail bb))
            }