7

我有一个“压缩”的值流,附加了该值的出现次数,例如:

let a = [ (),1; (),4; (),3;]

我想“解压缩”该序列并发出原始序列。我可以定义一个重复组合器来产生!为此

let rec repeat avalue n =  seq { if n > 0 then 
                                    yield avalue; yield! repeat avalue (n-1) }

let b = seq { for v,n in a do
                yield! repeat v n }  |> Seq.toList

有没有办法以组合的形式表达这种内联?

let c = a |> Seq.XXX(fun e -> ...) 
4

3 回答 3

6

您可以使用以下方法执行此操作Enumerable.Repeat

> Seq.collect Enumerable.Repeat [ 1, 2; 3, 4; 5, 6 ] |> List.ofSeq;;
val it : int list = [1; 1; 3; 3; 3; 3; 5; 5; 5; 5; 5; 5]
于 2013-04-02T18:02:58.273 回答
3

怎么样

let c = a |> Seq.collect (fun (v,i) -> [1..i] |> Seq.map (fun x -> v))

我不知道类似于 Enumerable.Repeat 的库函数;如果有人知道,请添加评论。

编辑

我发现了一个类似于 Enumerable.Repeat 的库函数,虽然它在List模块中:

let c = a |> Seq.collect (fun (v,i) -> List.replicate i v)

如果源序列中的对被颠倒,这会更优雅:

let c = a |> Seq.collect ((<||) List.replicate)

所以似乎 Enumerable.Repeat (如在接受的答案中)确实是最好的解决方案,因为它的元组参数与序列元素匹配:

let c = a |> Seq.collect Enumerable.Repeat

如果有人知道保留在 F# 库中的类似优雅的解决方案,请添加评论;谢谢。

于 2013-04-02T18:03:49.173 回答
3
let rec repeat (item,n) = seq { if n > 0 then yield item; yield! repeat(item, n-1)}
a |> Seq.collect repeat

例如,

[('a',2); ('b',2)] |> Seq.collect repeat

val it: seq<char> = seq ['a';'a';'b';'b']
于 2013-04-02T18:08:15.440 回答