33module Map
44
55open System.Collections .Generic
6- open Fable.Collections
7- open Fable.Core
86
97[<NoEquality; NoComparison>]
108[<AllowNullLiteral>]
@@ -136,30 +134,26 @@ module MapTree =
136134 elif c = 0 then MapTree( k, v)
137135 else MapTreeNode ( k, v, m, empty, 2 ) :> MapTree< 'Key, 'Value>
138136
139- let rec tryGetValue ( comparer : IComparer < 'Key >) k ( v : ref < 'Value >) ( m : MapTree < 'Key , 'Value >) =
140- if isEmpty m then false
137+ let rec tryGetValue ( comparer : IComparer < 'Key >) k ( m : MapTree < 'Key , 'Value >) =
138+ if isEmpty m then false , Unchecked.defaultof < 'Value >
141139 else
142140 let c = comparer.Compare( k, m.Key)
143- if c = 0 then v := m.Value; true
141+ if c = 0 then true , m.Value
144142 else
145143 match m with
146144 | :? MapTreeNode< 'Key, 'Value> as mn ->
147- tryGetValue comparer k v ( if c < 0 then mn.Left else mn.Right)
148- | _ -> false
145+ tryGetValue comparer k ( if c < 0 then mn.Left else mn.Right)
146+ | _ -> false , Unchecked.defaultof < 'Value >
149147
150148 let find ( comparer : IComparer < 'Key >) k ( m : MapTree < 'Key , 'Value >) =
151- let mutable v = Unchecked.defaultof< 'Value>
152- if tryGetValue comparer k ( ref v) m then
153- v
154- else
155- raise ( KeyNotFoundException())
149+ match tryGetValue comparer k m with
150+ | true , v -> v
151+ | false , _ -> raise ( KeyNotFoundException())
156152
157153 let tryFind ( comparer : IComparer < 'Key >) k ( m : MapTree < 'Key , 'Value >) =
158- let mutable v = Unchecked.defaultof< 'Value>
159- if tryGetValue comparer k ( ref v) m then
160- Some v
161- else
162- None
154+ match tryGetValue comparer k m with
155+ | true , v -> Some v
156+ | false , _ -> None
163157
164158 let partition1 ( comparer : IComparer < 'Key >) ( f : OptimizedClosures.FSharpFunc < _ , _ , _ >) k v ( acc1 , acc2 ) =
165159 if f.Invoke ( k, v) then ( add comparer k v acc1, acc2) else ( acc1, add comparer k v acc2)
@@ -502,7 +496,8 @@ module MapTree =
502496 else None)
503497
504498[<Sealed>]
505- [<CompiledName( " FSharpMap" ); Replaces( " Microsoft.FSharp.Collections.FSharpMap`2" ) >]
499+ [<CompiledName( " FSharpMap" ) >]
500+ [<Fable.Core.Replaces( " Microsoft.FSharp.Collections.FSharpMap`2" ) >]
506501type Map <[< EqualityConditionalOn >] 'Key , [<EqualityConditionalOn; ComparisonConditionalOn>] 'Value when 'Key : comparison >( comparer : IComparer < 'Key >, tree : MapTree < 'Key , 'Value >) =
507502
508503 // [<System.NonSerialized>]
@@ -631,9 +626,11 @@ type Map<[<EqualityConditionalOn>]'Key, [<EqualityConditionalOn; ComparisonCondi
631626 member m.Remove key =
632627 new Map< 'Key, 'Value>( comparer, MapTree.remove comparer key tree)
633628
634- [<OverloadSuffix( " " ) >]
629+ [<Fable.Core. OverloadSuffix( " " ) >]
635630 member __.TryGetValue ( key : 'Key , value : 'Value ref ) =
636- MapTree.tryGetValue comparer key value tree
631+ match MapTree.tryGetValue comparer key tree with
632+ | true , v -> value := v; true
633+ | false , _ -> false
637634
638635 member m.TryFind key =
639636// #if TRACE_SETS_AND_MAPS
@@ -695,7 +692,7 @@ type Map<[<EqualityConditionalOn>]'Key, [<EqualityConditionalOn; ComparisonCondi
695692 | _ ->
696693 invalidArg " obj" " not comparable"
697694
698- interface IMutableMap< 'Key, 'Value> with
695+ interface Fable.Collections. IMutableMap< 'Key, 'Value> with
699696 member this.size = this.Count
700697 member __.clear () = failwith " Map cannot be mutated"
701698 member __.delete ( _ ) = failwith " Map cannot be mutated"
@@ -793,7 +790,7 @@ let containsKey key (table: Map<_, _>) =
793790 table.ContainsKey key
794791
795792// [<CompiledName("Iterate")>]
796- let iter action ( table : Map < _ , _ >) =
793+ let iterate action ( table : Map < _ , _ >) =
797794 table.Iterate action
798795
799796// [<CompiledName("TryPick")>]
@@ -819,7 +816,7 @@ let partition predicate (table: Map<_, _>) =
819816 table.Partition predicate
820817
821818// [<CompiledName("ForAll")>]
822- let forall predicate ( table : Map < _ , _ >) =
819+ let forAll predicate ( table : Map < _ , _ >) =
823820 table.ForAll predicate
824821
825822// [<CompiledName("Map")>]
@@ -871,6 +868,34 @@ let toArray (table: Map<_, _>) =
871868let empty < 'Key , 'Value when 'Key : comparison > =
872869 Map< 'Key, 'Value>. Empty
873870
871+ let createMutable ( source : KeyValuePair < 'Key , 'Value > seq ) ( [<Fable.Core.Inject>] comparer : IEqualityComparer < 'Key >) =
872+ let map = Fable.Collections.MutableMap( source, comparer)
873+ map :> Fable.Collections.IMutableMap<_,_>
874+
875+ let groupBy ( projection : 'T -> 'Key ) ( xs : 'T seq ) ( [<Fable.Core.Inject>] comparer : IEqualityComparer < 'Key >): ( 'Key * 'T seq ) seq =
876+ let dict : Fable.Collections.IMutableMap < _ , ResizeArray < 'T >> = createMutable Seq.empty comparer
877+
878+ // Build the groupings
879+ for v in xs do
880+ let key = projection v
881+ if dict.has( key) then dict.get( key) .Add( v)
882+ else dict.set( key, ResizeArray [ v]) |> ignore
883+
884+ // Mapping shouldn't be necessary because KeyValuePair compiles
885+ // as a tuple, but let's do it just in case the implementation changes
886+ dict |> Seq.map ( fun kv -> kv.Key, upcast kv.Value)
887+
888+ let countBy ( projection : 'T -> 'Key ) ( xs : 'T seq ) ( [<Fable.Core.Inject>] comparer : IEqualityComparer < 'Key >): ( 'Key * int ) seq =
889+ let dict = createMutable Seq.empty comparer
890+
891+ for value in xs do
892+ let key = projection value
893+ if dict.has( key) then dict.set( key, dict.get( key) + 1 )
894+ else dict.set( key, 1 )
895+ |> ignore
896+
897+ dict |> Seq.map ( fun kv -> kv.Key, kv.Value)
898+
874899// [<CompiledName("Count")>]
875900let count ( table : Map < _ , _ >) =
876901 table.Count
0 commit comments