F# and List manipulations

I am preparing for a Beginning F# dojo for TRINUG tomorrow and I decided to do a presentation of Seq.GroupBy, Seq.CountBy, and Seq.SumBy for tuples.  It is not apparent by the same the difference among these constructs and I think having a knowledge of them is indispensible when doing any kind of list analysis.

I started with a basic list like so:

  1. let data = [("A",1);("A",3);("B",2);("C",1)]

I then ran a GroupBy through the REPL and got the following results:

  1. let grouping = data
  2.                 |> Seq.groupBy(fun (letter,number) -> letter)
  3.                 |> Seq.iter (printfn "%A")

  1. ("A", seq [("A", 1); ("A", 3)])
  2. ("B", seq [("B", 2)])
  3. ("C", seq [("C", 1)])

I then ran a CountBy through the REPL and got the following results:

  1. let counting = data
  2.                 |> Seq.countBy(fun (letter,number) -> letter)
  3.                 |> Seq.iter (printfn "%A")

  1. ("A", 2)
  2. ("B", 1)
  3. ("C", 1)

I then ran a SumBy through the REPL and got the following results:

  1. let summing = data
  2.                 |> Seq.sumBy(fun (letter,number) -> number)
  3.                 |> printfn "%A"

  1. 7

Now the fun begins.  I combined a GroupBy and a CountBy through the REPL and got the following results:

  1. let groupingAndCounting = data
  2.                         |> Seq.groupBy(fun (letter,number) -> letter)
  3.                         |> Seq.map(fun (letter,sequence) -> (letter,sequence |> Seq.countBy snd))
  4.                         |> Seq.iter (printfn "%A")

  1. ("A", seq [(1, 1); (3, 1)])
  2. ("B", seq [(2, 1)])
  3. ("C", seq [(1, 1)])

Next I combined a GroupBy and a SumBy through the REPL and got the following results:

  1. let groupingAndSumming = data
  2.                             |> Seq.groupBy(fun (letter,number) -> letter)
  3.                             |> Seq.map(fun (letter,sequence) -> (letter,sequence |> Seq.sumBy snd))
  4.                             |> Seq.iter (printfn "%A")

  1. ("A", 4)
  2. ("B", 2)
  3. ("C", 1)

I then combined all three:

  1. let groupingAndCountingSummed = data
  2.                                 |> Seq.groupBy(fun (letter,number) -> letter)
  3.                                 |> Seq.map(fun (letter,sequence) -> (letter,sequence |> Seq.countBy snd))
  4.                                 |> Seq.map(fun (letter,sequence) -> (letter,sequence |> Seq.sumBy snd))
  5.                                 |> Seq.iter (printfn "%A")

  1. ("A", 2)
  2. ("B", 1)
  3. ("C", 1)

With this in hand, I created a way of both counting and summing the second value of a tuple, which is a pretty common task:

  1. let revisedData =
  2.     let summed = data
  3.                     |> Seq.groupBy(fun (letter,number) -> letter)
  4.                     |> Seq.map(fun (letter,sequence) -> (letter,sequence |> Seq.sumBy snd))
  5.     let counted = data
  6.                     |> Seq.groupBy(fun (letter,number) -> letter)
  7.                     |> Seq.map(fun (letter,sequence) -> (letter,sequence |> Seq.countBy snd))
  8.                     |> Seq.map(fun (letter,sequence) -> (letter,sequence |> Seq.sumBy snd))
  9.     Seq.zip summed counted
  10.                     |> Seq.map(fun ((letter,summed),(letter,counted)) -> letter,summed,counted)
  11.                     |> Seq.iter (printfn "%A")

  1. ("A", 4, 2)
  2. ("B", 2, 1)
  3. ("C", 1, 1)

Finally, Mathias pointed out that I could use this as an entry to Deddle.  Which is a really good idea….

 

 

2 Responses to F# and List manipulations

  1. Pingback: F# Weekly #17, 2014 | Sergey Tihon's Blog

  2. Pingback: 5/1/2014 Article Links | The Puntastic Programmer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: