Jamie Dixon
Jamie Dixon

Reputation: 4302

F# transforming and aggregating a list of lists

I have the following set of data

let results = [[true;false;true];[true;true;false];[false;false;false]]

I want to turn it into

let summary = [2;1;1]

Is this something that can be done of the box? I was thinking the List.Collect but I can't get it to work.

Thanks in advance

Upvotes: 3

Views: 115

Answers (1)

Tomas Petricek
Tomas Petricek

Reputation: 243096

Based on your sample, I suppose that you want to sum the number of true values in the 1st, 2nd, 3rd etc. elements of the input lists, respectively.

One way to do this is to turn the list of booleans into list of numbers containing ones or zeros and then aggregate the lists. So, for your input, the list with numbers will be:

[[1; 0; 1]; [1; 1; 0]; [0; 0; 0]]

This we can easily get using nested List.map:

results |> List.map (List.map (fun b -> if b then 1 else 0))

Now you just need to zip the lists and add their corresponding numbers. Given the first two lists, you can do it using List.map2 as follows:

List.map2 (+) [1; 0; 1] [1; 1; 0] = [2; 1; 1]

The whole thing can be written as a single nice pipeline using partial application:

results
|> List.map (List.map (fun b -> if b then 1 else 0))
|> List.reduce (List.map2 (+))

Upvotes: 6

Related Questions