我有一个'压缩'的值流,附加了该值的出现次数,例如:
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 -> ...)
答案 0 :(得分: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]
答案 1 :(得分: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(如在接受的答案中)确实提供了最佳解决方案,因为它的tupled参数与序列元素匹配:
let c = a |> Seq.collect Enumerable.Repeat
如果有人知道保留在F#库中的同样优雅的解决方案,请添加评论;感谢。
答案 2 :(得分: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']