0

除了编写一个产生值的循环之外,是否有一种简单/干净的函数式方法可以在序列中创建滞后(前一个值)。

例如。如果我的序列是1 2 3 4 5 6 7 8 9 10并且我的滞后是1返回一个元组

(Some(1), None), (Some(2), Some(1)), (Some(3), Some(2))...(Some(10), Some(9))

一个滞后2会给(Some(1), None), (Some(2), None), (Some(3), Some(1))...

使用循环显然很容易编写此代码,但这是正确的方式吗?

4

2 回答 2

3

一种方法是使用 Seq 模块中的函数:

let lag n sequence =
    sequence
    |> Seq.map Some
    |> Seq.append (Seq.init n (fun _ -> None))
    |> Seq.zip sequence

lag 2 [1..5] |> Seq.toList
> [(1, null); (2, null); (3, Some 1); (4, Some 2); (5, Some 3)]
于 2013-02-28T15:40:23.617 回答
1

petebu 的答案(一旦纠正了一些错误)是一个更好的答案。但无论如何我都会把它留在这里。

let withLag n (source: seq<_>) =
  source
    |> Seq.windowed n
    |> Seq.append (Seq.init n (fun _ -> [||]))
    |> Seq.zip source
    |> Seq.map (fun (x, arr) ->
      let laggedValue = if arr.Length > 0 then Some arr.[0] else None
      (x, laggedValue))

let l = List.init 5 id
l |> withLag 2 |> Seq.toList |> printfn "%A"

> [(0, null); (1, null); (2, Some 0); (3, Some 1); (4, Some 2)]
于 2013-02-28T15:39:53.990 回答