2011-03-29 20 views
5

Ok, sembra che dovrebbe essere facile, ma non lo capisco. Se ho una sequenza di numeri, come faccio a generare una nuova sequenza composta dai totali correnti? ad esempio per una sequenza [1; 2; 3; 4], voglio mapparla a [1; 3; 6; 10]. In un modo adeguatamente funzionale.f # sequenza del totale parziale

risposta

14

Uso List.scan:

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

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

Seq.scan -based implementazione:

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

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

Questo è molto bello, tuttavia speravo di farlo per una sequenza piuttosto che per una lista. – Aidan

+0

@Aidan: modificato per aggiungere l'implementazione Seq.scan corretta. – ildjarn

+0

Cool, questo è quello. Grazie. – Aidan

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

Con le liste:

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

Edit: Un altro modo con le sequenze:

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

Sì, c'è una variabile mutabile, ma trovo più leggibile (se si desidera ottenere liberarsi dello 0 iniziale).

+0

cool, grazie. Tuttavia sembra che generi una sequenza più grande, con uno 0 iniziale, non sembra una vera mappa. – Aidan

0

Non sono sicuro questo è il modo migliore, ma dovrebbe fare il trucco

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

Un'altra variazione usando Seq.scan (Seq.skip 1 si sbarazza del leader zero):

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

+1 La risposta più semplice ancora. – Daniel

+2

Grazie Daniel, F # nutre la mia malattia per soluzioni succinte ed eleganti. –

+1

Anch'io. Temo che il mio destino di programmatore si intreccia con F #. – Daniel

Problemi correlati