2013-04-02 26 views
7

ho un flusso 'compresso' di valore a cui è collegato il numero di occorrenza di tale valore, per esempio:Ripetere sequenze in F #

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

Vorrei 'decomprimere' quella sequenza ed emettere il sequenza originale. Potrei definire un combinatore di ripetizioni per cedere! a tal fine

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 

C'è un modo per esprimere quello in linea, nella forma di una composizione?

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

risposta

6

È possibile farlo utilizzando 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

ah, non sapevo che uno! – nicolas

+1

Quindi questo è il migliore per le tuple, che è il contesto della mia domanda. Quindi questa è la risposta più funzionale. – nicolas

+2

Ora c'è anche ['List.replicate <'T>'] (https://msdn.microsoft.com/en-us/library/ee353665.aspx). –

3

Come su

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

Non so una funzione di libreria simile a Enumerable.Repeat; se qualcuno ne conosce uno, per favore aggiungi un commento.

EDIT

Ho trovato una funzione di libreria simile a Enumerable.Repeat, anche se è nel modulo List:

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

Questo sarebbe più elegante se le coppie nell'origine sequenza sono stati invertiti:

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

Quindi sembra che Enumerable.Re torba (come nella risposta accettata) effettivamente rendere la soluzione migliore, dal momento che il suo argomento tupled soddisfa gli elementi di sequenza:

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

Se qualcuno sa di una soluzione simile elegante che rimane all'interno della libreria F #, si prega di aggiungere un commento ; Grazie.

+0

Bello, non sapevo che esistesse una funzione F # ('<||') simile a 'uncurry' di Haskell! – MisterMetaphor

3
let rec repeat (item,n) = seq { if n > 0 then yield item; yield! repeat(item, n-1)} 
a |> Seq.collect repeat 

Per esempio,

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

val it: seq<char> = seq ['a';'a';'b';'b'] 
+0

bello. anche se è |> Seq.collect (fun (item, n) -> repeat item n) – nicolas

+1

La mia versione con argomento 'repeat' tupla permette di eliminare lambda nel combinatore. –