Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initial state in F# List.scan

Tags:

f#

I have a simple problem and as I'm an F# newbie I can't seem to figure out how to do this. I have a list of tuples:

let l = [ (a, 2); (b, 3); (c, 2); (d, 6) ]

that I want to transform into this:

let r = [ (a, 2); (b, 5); (c, 7); (d, 13) ]

This simply adds the values of the second element in each tuple: 2 + 3 + 2 + 6. The objects a, b, c and d are complex objects that I simply want to keep.

I thought I should use List.scan for this. It takes a list, threads an accumulator through the computation and returns a list:

let r = l |> List.scan (fun (_, s) (o, i) -> (o, s + i)) (??, 0) |> List.tail

But I don't know what to fill in for the question marks. I'm not interested in the initial state except for the 0. And I don't want to specify some 'empty' instance of the first tuple element.

Or is there a simpler way of doing this?

like image 999
Ronald Wildenberg Avatar asked Dec 29 '22 08:12

Ronald Wildenberg


1 Answers

You can use first element as an initial state:

let l = [ ("a", 2); ("b", 3); ("c", 2); ("d", 6) ]

let x::xs = l
let res = (x, xs) ||> List.scan (fun (_, x) (o, n) -> o, x + n) // [("a", 2); ("b", 5); ("c", 7); ("d", 13)]

Special case with empty list should be processed separately

like image 181
desco Avatar answered Jan 07 '23 19:01

desco