1 people like it.

List Multipartition

Needed to partition a list into multiple groups, but couldn't find an existing way to do it. Have not put this as an extension method as needed it in an .fsx file which is loaded, but couldn't get extension method to work from that.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
// Partitions a list into a map of key->List<T> based on the 
// key returned by the call to discriminatorFunc
// Note that lists are in reversed order to the input...
let ListPartition (discriminatorFunc : 'V -> 'K) list = 
    let rec part (map:System.Collections.Generic.Dictionary<'K,'V list>) listTail =
        match listTail with
        | [] -> map
        | x :: tail -> let key = discriminatorFunc x
                       let res,list =  map.TryGetValue(key)
                       match res with
                       | false -> map.Add(key,[x])
                       | true -> map.[key] <- x :: list
                       part map tail

    part (new System.Collections.Generic.Dictionary<'K,'V list>()) list
val ListPartition : discriminatorFunc:('V -> 'K) -> list:'V list -> System.Collections.Generic.Dictionary<'K,'V list> (requires equality)

Full name: Script.ListPartition
val discriminatorFunc : ('V -> 'K) (requires equality)
Multiple items
val list : 'V list

--------------------
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val part : (System.Collections.Generic.Dictionary<'K,'V list> -> 'V list -> System.Collections.Generic.Dictionary<'K,'V list>) (requires equality)
val map : System.Collections.Generic.Dictionary<'K,'V list> (requires equality)
namespace System
namespace System.Collections
namespace System.Collections.Generic
Multiple items
type Dictionary<'TKey,'TValue> =
  new : unit -> Dictionary<'TKey, 'TValue> + 5 overloads
  member Add : key:'TKey * value:'TValue -> unit
  member Clear : unit -> unit
  member Comparer : IEqualityComparer<'TKey>
  member ContainsKey : key:'TKey -> bool
  member ContainsValue : value:'TValue -> bool
  member Count : int
  member GetEnumerator : unit -> Enumerator<'TKey, 'TValue>
  member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
  member Item : 'TKey -> 'TValue with get, set
  ...
  nested type Enumerator
  nested type KeyCollection
  nested type ValueCollection

Full name: System.Collections.Generic.Dictionary<_,_>

--------------------
System.Collections.Generic.Dictionary() : unit
System.Collections.Generic.Dictionary(capacity: int) : unit
System.Collections.Generic.Dictionary(comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
System.Collections.Generic.Dictionary(dictionary: System.Collections.Generic.IDictionary<'TKey,'TValue>) : unit
System.Collections.Generic.Dictionary(capacity: int, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
System.Collections.Generic.Dictionary(dictionary: System.Collections.Generic.IDictionary<'TKey,'TValue>, comparer: System.Collections.Generic.IEqualityComparer<'TKey>) : unit
val listTail : 'V list
val x : 'V
val tail : 'V list
val key : 'K (requires equality)
val res : bool
System.Collections.Generic.Dictionary.TryGetValue(key: 'K, value: byref<'V list>) : bool
System.Collections.Generic.Dictionary.Add(key: 'K, value: 'V list) : unit

More information

Link:http://fssnip.net/nx
Posted:10 years ago
Author:@BrockSamsonUK
Tags: list , partition