2013-04-02 50 views
7

我的值的「壓縮」流,其上連接該值的occurence的數量,例如:重複序列

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

回答

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] 
+0

啊,我不知道一個! – nicolas

+1

所以這一個是元組的最好的,這是我的問題的上下文。因此這是最實用的答案。 – nicolas

+2

現在還有['List.replicate <'T>'](https://msdn.microsoft.com/en-us/library/ee353665.aspx)。 –

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.Re泥煤(如在接受的答案)確實做出最好的解決方案,因爲它tupled參數序列的元素相匹配:

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

如果有人在F#庫中保持一個同樣優雅的解決方案的人都知道,請添加評論;謝謝。

+0

不錯,我不知道有一個F#函數('<||')類似於Haskell的'uncurry'! – MisterMetaphor

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'] 
+0

不錯的一個。雖然它是| | Seq.collect(fun(item,n) - > repeat item n) – nicolas

+1

我的帶tupled'repeat'參數的版本允許擺脫組合器中的lambda。 –