【问题标题】:Repeating sequences in F#F# 中的重复序列
【发布时间】:2013-04-02 17:49:06
【问题描述】:

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

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 -> ...) 

【问题讨论】:

    标签: f#


    【解决方案1】:

    您可以使用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]
    

    【讨论】:

    • 啊,我不知道那个!
    • 所以这个最适合元组,这是我问题的上下文。因此,这是最实用的答案。
    • 现在还有List.replicate<'T>
    【解决方案2】:
    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']
    

    【讨论】:

    • 不错的一个。虽然是 |> Seq.collect (fun (item,n) -> 重复项目 n)
    • 我的带有元组 repeat 参数的版本允许摆脱组合器中的 lambda。
    【解决方案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# 库中的类似优雅的解决方案,请添加评论;谢谢。

    【讨论】:

    • 很好,我不知道有一个类似于 Haskell 的 uncurry 的 F# 函数 (&lt;||)!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 1970-01-01
    • 2011-08-01
    相关资源
    最近更新 更多