4 people like it.

list function for cross tabulation and pivot tables

Convert a list of tuples into a crosstab of key with list of values with that key

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
// take an order list of tuple key value and convert to a crosstab of key & values
let crosstab set = Seq.fold (fun a (x,y) -> if (fst (List.head a)) = x then [(x,[y] @ (snd (List.head a)))] @ a.Tail else [(x,[y])] @ a) [(fst (Seq.head set),[])] set

(*
    takes advantage of tail of a single linked list being a list, to immutably accumulate without copying data.
    example with type anotation 

crosstab [(1,'a'); (1,'b');(1,'c');(2,'A');(2,'B');(3,'x')] = [(3, ['x']); (2, ['B'; 'A']); (1, ['c'; 'b'; 'a'])]

let crosstab (set : ('a * 'b) seq) : ('a * 'b list) list = 
    let keyofhead (a : ('a * 'b list) list) : 'a = fst (List.head a)
    let crosshead (a : ('a * 'b list) list) : 'b list = snd (List.head a)
    let statewithfirstkey : ('a * 'b list) list = [(fst (Seq.head set),[])]
    Seq.fold (fun a (x,y) -> if (keyofhead a) = x then [(x,[y] @ (crosshead a))] @ a.Tail else [(x,[y])] @ a) statewithfirstkey set
*)
val crosstab : set:seq<'a * 'b> -> ('a * 'b list) list (requires equality)
val set : seq<'a * 'b> (requires equality)
module Seq

from Microsoft.FSharp.Collections
val fold : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> 'State
val a : ('a * 'b list) list (requires equality)
val x : 'a (requires equality)
val y : 'b
val fst : tuple:('T1 * 'T2) -> 'T1
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
    interface IReadOnlyList<'T>
    interface IReadOnlyCollection<'T>
    interface IEnumerable
    interface IEnumerable<'T>
    member GetReverseIndex : rank:int * offset:int -> int
    member GetSlice : startIndex:int option * endIndex:int option -> 'T list
    member Head : 'T
    member IsEmpty : bool
    member Item : index:int -> 'T with get
    member Length : int
    ...
val head : list:'T list -> 'T
val snd : tuple:('T1 * 'T2) -> 'T2
property List.Tail: ('a * 'b list) list with get
val head : source:seq<'T> -> 'T

More information

Link:http://fssnip.net/7Tw
Posted:4 years ago
Author:Steve Channell
Tags: seq , crosstab , pivot