1
1
using System . Collections ;
2
2
using System . Collections . Generic ;
3
+ #if NET35
4
+ using System . Linq ;
5
+ #endif
3
6
#if PCL
4
7
using ArrayList = System . Collections . Generic . List < object > ;
5
8
#endif
@@ -12,7 +15,7 @@ namespace NetTopologySuite.Utilities
12
15
/// </summary>
13
16
public class CollectionUtil
14
17
{
15
-
18
+
16
19
/// <summary>
17
20
///
18
21
/// </summary>
@@ -40,7 +43,7 @@ public class CollectionUtil
40
43
public static IList Transform ( ICollection coll , FunctionDelegate < object > func )
41
44
{
42
45
IList result = new ArrayList ( ) ;
43
- foreach ( object obj in coll )
46
+ foreach ( object obj in coll )
44
47
result . Add ( func ( obj ) ) ;
45
48
return result ;
46
49
}
@@ -140,10 +143,10 @@ public static void Apply<T>(IEnumerable<T> coll, FunctionDelegate<T> func)
140
143
/// <returns></returns>
141
144
public static IList Select ( ICollection coll , FunctionDelegate < object , bool > func )
142
145
{
143
- IList result = new ArrayList ( ) ;
146
+ IList result = new ArrayList ( ) ;
144
147
foreach ( object obj in coll )
145
148
if ( func ( obj ) )
146
- result . Add ( obj ) ;
149
+ result . Add ( obj ) ;
147
150
return result ;
148
151
}
149
152
@@ -177,5 +180,74 @@ public static TOut[] Cast<TIn,TOut>(TIn[] array)
177
180
return res ;
178
181
}
179
182
183
+ internal static IEnumerable < T > StableSort < T > ( IEnumerable < T > items )
184
+ {
185
+ return StableSort ( items , Comparer < T > . Default ) ;
186
+ }
187
+
188
+ internal static IEnumerable < T > StableSort < T > ( IEnumerable < T > items , IComparer < T > comparer )
189
+ {
190
+ #if NET35
191
+ // LINQ's OrderBy is guaranteed to be a stable sort.
192
+ return items . OrderBy ( x => x , comparer ) ;
193
+ #else
194
+
195
+ // otherwise, tag each item with the index and sort the wrappers.
196
+ // if we're given a collection (and we always are), use its count
197
+ // to prevent unnecessary array copies.
198
+ var itemCollection = items as ICollection < T > ;
199
+ var taggedItems = itemCollection == null
200
+ ? new List < IndexTaggedItem < T > > ( )
201
+ : new List < IndexTaggedItem < T > > ( itemCollection . Count ) ;
202
+
203
+ int index = 0 ;
204
+ foreach ( var item in items )
205
+ {
206
+ taggedItems . Add ( new IndexTaggedItem < T > ( item , index ++ ) ) ;
207
+ }
208
+
209
+ taggedItems . Sort ( new IndexAwareComparer < T > ( comparer ) ) ;
210
+
211
+ var sorted = new List < T > ( taggedItems . Count ) ;
212
+ foreach ( var taggedItem in taggedItems )
213
+ {
214
+ sorted . Add ( taggedItem . Item ) ;
215
+ }
216
+
217
+ return sorted ;
218
+ #endif
219
+ }
220
+
221
+ #if ! NET35
222
+ private sealed class IndexTaggedItem < T >
223
+ {
224
+ internal readonly T Item ;
225
+ internal readonly int Index ;
226
+
227
+ internal IndexTaggedItem ( T item , int index )
228
+ {
229
+ this . Item = item ;
230
+ this . Index = index ;
231
+ }
232
+ }
233
+
234
+ private sealed class IndexAwareComparer < T > : Comparer < IndexTaggedItem < T > >
235
+ {
236
+ private readonly IComparer < T > primaryComparer ;
237
+
238
+ internal IndexAwareComparer ( IComparer < T > primaryComparer )
239
+ {
240
+ this . primaryComparer = primaryComparer ;
241
+ }
242
+
243
+ public override int Compare ( IndexTaggedItem < T > x , IndexTaggedItem < T > y )
244
+ {
245
+ int cmp = this . primaryComparer . Compare ( x . Item , y . Item ) ;
246
+
247
+ // compare equal elements by their index.
248
+ return cmp == 0 ? x . Index . CompareTo ( y . Index ) : cmp ;
249
+ }
250
+ }
251
+ #endif
180
252
}
181
253
}
0 commit comments