1
+ using System . Collections . Generic ;
2
+ using System . Text ;
3
+
4
+ namespace Core . Common . Extensions . BitStrap
5
+ {
6
+ /// <summary>
7
+ /// Bunch of utility extension methods to the generic Dictionary class.
8
+ /// These methods are intended to be System.Ling substitues as they do not generate garbage.
9
+ /// </summary>
10
+ public static class DictionaryExtensions
11
+ {
12
+ public struct Iterator < K , V >
13
+ {
14
+ private Dictionary < K , V > . Enumerator enumerator ;
15
+
16
+ public KeyValuePair < K , V > Current
17
+ {
18
+ get { return enumerator . Current ; }
19
+ }
20
+
21
+ public Iterator ( Dictionary < K , V > collection )
22
+ {
23
+ enumerator = collection . GetEnumerator ( ) ;
24
+ }
25
+
26
+ public Iterator < K , V > GetEnumerator ( )
27
+ {
28
+ return this ;
29
+ }
30
+
31
+ public bool MoveNext ( )
32
+ {
33
+ return enumerator . MoveNext ( ) ;
34
+ }
35
+ }
36
+
37
+ /// <summary>
38
+ /// Use this method to iterate a Dictionary in a foreach loop but with no garbage
39
+ /// </summary>
40
+ /// <example>
41
+ /// foreach( var pair in myDictionary.Iter() )
42
+ /// {
43
+ /// // code goes here...
44
+ /// }
45
+ /// </example>
46
+ /// <typeparam name="K"></typeparam>
47
+ /// <typeparam name="V"></typeparam>
48
+ /// <param name="collection"></param>
49
+ /// <returns></returns>
50
+ public static Iterator < K , V > Iter < K , V > ( this Dictionary < K , V > collection )
51
+ {
52
+ return new Iterator < K , V > ( collection ) ;
53
+ }
54
+
55
+ /// <summary>
56
+ /// Behaves like TryGetValue however nicer and returning an Option<V>.
57
+ /// </summary>
58
+ /// <typeparam name="K"></typeparam>
59
+ /// <typeparam name="V"></typeparam>
60
+ /// <param name="collection"></param>
61
+ /// <param name="key"></param>
62
+ /// <returns></returns>
63
+ public static Option < V > Get < K , V > ( this Dictionary < K , V > collection , K key )
64
+ {
65
+ V value ;
66
+ if ( collection . TryGetValue ( key , out value ) )
67
+ return new Option < V > ( value ) ;
68
+
69
+ return Functional . None ;
70
+ }
71
+
72
+ /// <summary>
73
+ /// Behaves like System.Linq.Count however it does not generate garbage.
74
+ /// </summary>
75
+ /// <typeparam name="K"></typeparam>
76
+ /// <typeparam name="V"></typeparam>
77
+ /// <param name="collection"></param>
78
+ /// <param name="predicate"></param>
79
+ /// <returns></returns>
80
+ public static int Count < K , V > ( this Dictionary < K , V > collection , System . Predicate < KeyValuePair < K , V > > predicate )
81
+ {
82
+ if ( predicate == null )
83
+ return 0 ;
84
+
85
+ var count = 0 ;
86
+ for ( var enumerator = collection . GetEnumerator ( ) ; enumerator . MoveNext ( ) ; )
87
+ {
88
+ if ( predicate ( enumerator . Current ) )
89
+ count ++ ;
90
+ }
91
+
92
+ return count ;
93
+ }
94
+
95
+ /// <summary>
96
+ /// Behaves like System.Linq.All however it does not generate garbage.
97
+ /// </summary>
98
+ /// <typeparam name="K"></typeparam>
99
+ /// <typeparam name="V"></typeparam>
100
+ /// <param name="collection"></param>
101
+ /// <param name="predicate"></param>
102
+ /// <returns></returns>
103
+ public static bool All < K , V > ( this Dictionary < K , V > collection , System . Predicate < KeyValuePair < K , V > > predicate )
104
+ {
105
+ if ( predicate == null )
106
+ return false ;
107
+
108
+ for ( var enumerator = collection . GetEnumerator ( ) ; enumerator . MoveNext ( ) ; )
109
+ {
110
+ if ( ! predicate ( enumerator . Current ) )
111
+ return false ;
112
+ }
113
+
114
+ return true ;
115
+ }
116
+
117
+ /// <summary>
118
+ /// Behaves like System.Linq.Any however it does not generate garbage.
119
+ /// </summary>
120
+ /// <typeparam name="K"></typeparam>
121
+ /// <typeparam name="V"></typeparam>
122
+ /// <param name="collection"></param>
123
+ /// <returns></returns>
124
+ public static bool Any < K , V > ( this Dictionary < K , V > collection )
125
+ {
126
+ return collection . Count > 0 ;
127
+ }
128
+
129
+ /// <summary>
130
+ /// Behaves like System.Linq.Any however it does not generate garbage.
131
+ /// </summary>
132
+ /// <typeparam name="K"></typeparam>
133
+ /// <typeparam name="V"></typeparam>
134
+ /// <param name="collection"></param>
135
+ /// <param name="predicate"></param>
136
+ /// <returns></returns>
137
+ public static bool Any < K , V > ( this Dictionary < K , V > collection , System . Predicate < KeyValuePair < K , V > > predicate )
138
+ {
139
+ if ( predicate == null )
140
+ return false ;
141
+
142
+ for ( var enumerator = collection . GetEnumerator ( ) ; enumerator . MoveNext ( ) ; )
143
+ {
144
+ if ( predicate ( enumerator . Current ) )
145
+ return true ;
146
+ }
147
+
148
+ return false ;
149
+ }
150
+
151
+ /// <summary>
152
+ /// Behaves like System.Linq.FirstOrDefault however it does not generate garbage.
153
+ /// </summary>
154
+ /// <typeparam name="K"></typeparam>
155
+ /// <typeparam name="V"></typeparam>
156
+ /// <param name="collection"></param>
157
+ /// <returns></returns>
158
+ public static Option < KeyValuePair < K , V > > First < K , V > ( this Dictionary < K , V > collection )
159
+ {
160
+ var enumerator = collection . GetEnumerator ( ) ;
161
+ if ( enumerator . MoveNext ( ) )
162
+ return new Option < KeyValuePair < K , V > > ( enumerator . Current ) ;
163
+
164
+ return Functional . None ;
165
+ }
166
+
167
+ /// <summary>
168
+ /// Behaves like System.Linq.FirstOrDefault however it does not generate garbage.
169
+ /// </summary>
170
+ /// <typeparam name="K"></typeparam>
171
+ /// <typeparam name="V"></typeparam>
172
+ /// <param name="collection"></param>
173
+ /// <param name="predicate"></param>
174
+ /// <returns></returns>
175
+ public static Option < KeyValuePair < K , V > > First < K , V > ( this Dictionary < K , V > collection , System . Predicate < KeyValuePair < K , V > > predicate )
176
+ {
177
+ for ( var enumerator = collection . GetEnumerator ( ) ; enumerator . MoveNext ( ) ; )
178
+ {
179
+ if ( predicate ( enumerator . Current ) )
180
+ return new Option < KeyValuePair < K , V > > ( enumerator . Current ) ;
181
+ }
182
+
183
+ return Functional . None ;
184
+ }
185
+
186
+ /// <summary>
187
+ /// Pretty format an dictionary as "{ k1=e1, k2=e2, k3=e3, ..., kn=en }".
188
+ /// </summary>
189
+ /// <typeparam name="K"></typeparam>
190
+ /// <typeparam name="V"></typeparam>
191
+ /// <param name="collection"></param>
192
+ /// <returns></returns>
193
+ public static string ToStringFull < K , V > ( this Dictionary < K , V > collection )
194
+ {
195
+ if ( collection == null )
196
+ return "null" ;
197
+ if ( collection . Count <= 0 )
198
+ return "{}" ;
199
+
200
+ var sb = new StringBuilder ( ) ;
201
+
202
+ sb . Append ( "{ " ) ;
203
+
204
+ for ( var enumerator = collection . GetEnumerator ( ) ; enumerator . MoveNext ( ) ; )
205
+ {
206
+ sb . Append ( enumerator . Current . Key . ToString ( ) ) ;
207
+ sb . Append ( "=" ) ;
208
+ sb . Append ( enumerator . Current . Value . ToString ( ) ) ;
209
+ sb . Append ( ", " ) ;
210
+ }
211
+
212
+ sb . Remove ( sb . Length - 2 , 2 ) ;
213
+ sb . Append ( " }" ) ;
214
+
215
+ return sb . ToString ( ) ;
216
+ }
217
+ }
218
+ }
0 commit comments