4 people like it.
Like the snippet!
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