2013-04-02 14 views
7

I einen ‚komprimierten‘ Strom von Wert zu dem die Anzahl des Auftretens dieses Wertes angebracht, zum Beispiel:Repeating-Sequenzen in F #

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

Ich mag ‚dekomprimieren‘, die Sequenz und emittieren die ursprüngliche Sequenz. Ich könnte einen Wiederholungskombinator definieren, um zu ergeben! zu diesem Zweck

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 

Gibt es eine Möglichkeit, das inline auszudrücken, in Form einer Zusammensetzung?

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

Antwort

6

Sie können diese Enumerable.Repeat mit tun:

> 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, ich weiß nicht, dass man! – nicolas

+1

Also dieses ist das beste für Tupel, das ist der Kontext meiner Frage. Daher ist dies die funktionalste Antwort. – nicolas

+2

Es gibt jetzt auch ['List.replicate <'T>'] (https://msdn.microsoft.com/en-us/library/ee353665.aspx). –

3

Wie wäre es

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

Ich habe keine Bibliotheksfunktion ähnlich wie Enumerable.Repeat wissen; Wenn jemand davon weiß, fügen Sie bitte einen Kommentar hinzu.

EDIT

ich eine Bibliotheksfunktion ähnlich wie Enumerable.Repeat gefunden haben, obwohl es in der List Modul ist:

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

Dieses eleganter wäre, wenn die Paare in der Quelle Reihenfolge wurde umgekehrt:

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

So scheint es, dass Enumerable.Re Torf (wie in der Antwort akzeptiert) ist in der Tat die beste Lösung zu machen, da seine fach vervielfachten Argument der Elemente Sequenz entspricht:

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

Wenn jemand eine ähnlich elegante Lösung kennt, die in der F # Bibliothek bleibt, fügen Sie bitte einen Kommentar ; Vielen Dank.

+0

Schön, ich wusste nicht, dass es eine F # -Funktion ('<||') gibt, die Haskells "Uncurry" ähnelt! – MisterMetaphor

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

Zum Beispiel

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

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

nett. obwohl es ist |> Seq.collect (Spaß (Artikel, n) -> Punkt wiederholen n) – nicolas

+1

Meine Version mit tupled 'repeat' Argument ermöglicht es, Lambda im Kombinator loszuwerden. –