我必须编写一个从无限序列开始的函数,并返回如下:
输入sq0 = {x0,x1,x2,x3,... xn}
输出序列 - > {[x0],[x0; x1],[x0; x1; x2] [x0; x1; x2; x3] ......}
你可以帮我吗?我试过这个
let rec pref sq = seq {
yield [Seq.nth 0 sq]
let x1 = Seq.nth 1 sq
yield [x1] @ [x0]
yield! pref Seq.skip 2 sq
}
答案 0 :(得分:4)
您可以使用Seq.scan
:
let createSeq s =
s
|> Seq.scan (fun x y -> x @ [y]) []
|> Seq.skip 1
答案 1 :(得分:3)
这很有效但可能更有效率:
let input =
Seq.initInfinite (fun i -> sprintf "x%i" i)
let output =
input
|> Seq.mapi (fun i _ -> input |> Seq.take (i + 1) |> Seq.toList)
答案 2 :(得分:1)
有一点可变性没有错。
let gen xs =
let ra = ResizeArray()
seq{ for x in xs do
ra.Add x
yield Seq.toList ra }
gen ["x0";"x1";"x2";"x3";"x4"]
|> printfn "%A"
输出:
seq [["x0"]; ["x0"; "x1"]; ["x0"; "x1"; "x2"]; ["x0"; "x1"; "x2"; "x3"]; ...]
答案 3 :(得分:0)
如果你已经有了累积元素的序列,古斯塔沃的答案也不错。
否则,这个递归定义也可以起作用。
let rec createSeq = Seq.scan List.append List.empty init
and init = seq {yield [1]; yield! createSeq}
let l = createSeq |> Seq.take 5 |> Seq.toArray
请注意,Sequence是一个接口,因此根据所使用的实现和访问模式存在许多性能配置文件。
答案 4 :(得分:0)
如果性能是您之后的,那么从时间角度和内存使用角度来看,这就是您想要的(这是编译器中Seq.scan
的精简版本):
let scan z (source : seq<'T>) =
seq { let zref : ('T list ref) = ref z
yield !zref
use ie = source.GetEnumerator()
while ie.MoveNext() do
zref := ie.Current :: !zref
yield !zref }
let input = Seq.initInfinite (fun i -> sprintf "x%i" i)
let createSeqCustom s =
s
|> scan []
|> Seq.skip 1
> System.GC.Collect()
> let l = input |> createSeq |> Seq.take 2000 |> Seq.toArray
Real: 00:00:00.007, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
与下一个最快的答案相比:
let createSeq s =
s
|> Seq.scan (fun x y -> x @ [y]) []
|> Seq.skip 1
> System.GC.Collect()
> let l2 = input |> createSeq |> Seq.take 2000 |> Seq.toArray
Real: 00:00:00.293, CPU: 00:00:00.296, GC gen0: 6, gen1: 4, gen2: 0
重要的区别是垃圾收集。此实现还将处理更大的序列(注意200,000个项目):
> System.GC.Collect()
> let l = input |> createSeqCustom |> Seq.take 200000 |> Seq.toArray
Real: 00:00:00.406, CPU: 00:00:00.406, GC gen0: 11, gen1: 5, gen2: 0
而其他实现在更小的输入上耗尽内存(注意要采集的是20,000个项目):
> let l2 = input |> createSeq |> Seq.take 20000 |> Seq.toArray
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
Stopped due to error