2011-03-29 21 views
5

OK, wygląda na to, że powinno być łatwo, ale po prostu nie rozumiem. Jeśli mam ciąg liczb, w jaki sposób mogę wygenerować nową sekwencję złożoną z działających liczb całkowitych? np. dla sekwencji [1; 2; 3; 4], chcę odwzorować ją na [1; 3; 6; 10]. W odpowiednio funkcjonalny sposób.f # sekwencja bieżącej sumy

Odpowiedz

14

Zastosowanie List.scan:

let runningTotal = List.scan (+) 0 >> List.tail 

[1; 2; 3; 4] 
|> runningTotal 
|> printfn "%A" 

Seq.scan -na realizacja:

let runningTotal seq' = (Seq.head seq', Seq.skip 1 seq') ||> Seq.scan (+) 

{ 1..4 } 
|> runningTotal 
|> printfn "%A" 
+0

To jest bardzo fajne, jednak miałem nadzieję, że zrobię to dla Sekwencji, a nie dla listy. – Aidan

+0

@Aidan: Edytowano w celu dodania właściwej implementacji Seq.scan. – ildjarn

+0

Fajnie, to ten. Dziękuję Ci. – Aidan

5
> Seq.scan (fun acc n -> acc + n) 0 [1;2;3;4];; 
val it : seq<int> = seq [0; 1; 3; 6; ...] 

Z list:

> [1;2;3;4] |> List.scan (fun acc n -> acc + n) 0 |> List.tail;; 
val it : int list = [1; 3; 6; 10] 

Edit: Innym sposobem z sekwencji:

let sum s = seq { 
    let x = ref 0 
    for i in s do 
     x := !x + i 
     yield !x 
} 

Tak, istnieje zmienna zmienny, ale uważam, że bardziej czytelny (jeśli chcesz dostać pozbądź się wiodącego 0).

+0

fajnie, dziękuję. Wydaje się jednak, że generuje większą sekwencję, z początkowym 0, nie wydaje się prawdziwą mapą. – Aidan

0

Nie wiem, to jest najlepszy sposób, ale powinien on rade

let input = [1; 2; 3; 4] 
    let runningTotal = 
    (input, 0) 
    |> Seq.unfold (fun (list, total) -> 
     match list with 
     | [] -> 
     None 
     | h::t -> 
     let total = total + h 
     total, (t, total) |> Some) 
    |> List.ofSeq 
13

Kolejna wariacja użyciu Seq.scan (Seq.skip 1 pozbywa się prowadzenia zero):

> {1..4} |> Seq.scan (+) 0 |> Seq.skip 1;; 
val it : seq<int> = seq [1; 3; 6; 10] 
+0

+1 Najprostsza odpowiedź. – Daniel

+2

Dzięki Daniel, F # karmi moją chorobę za zwięzłe, eleganckie rozwiązania. –

+1

Ja też. Obawiam się, że mój los jako programisty przeplata się z F #. – Daniel