1
- using System . Collections . Generic ;
1
+ using System ;
2
+ using System . Collections ;
3
+ using System . Collections . Generic ;
2
4
using System . Linq ;
3
5
using JetBrains . Annotations ;
4
6
using Linq . Extras . Internal ;
@@ -14,10 +16,39 @@ partial class XEnumerable
14
16
/// <param name="source">The source sequence.</param>
15
17
/// <returns>A sequence of elements paired with their index in the sequence.</returns>
16
18
[ Pure ]
17
- public static IEnumerable < IndexedItem < TSource > > WithIndex < TSource > (
19
+ public static WithIndexEnumerable < TSource > WithIndex < TSource > (
18
20
[ NotNull ] this IEnumerable < TSource > source )
19
21
{
20
- return source . Select ( ( item , index ) => new IndexedItem < TSource > ( item , index ) ) ;
22
+ source . CheckArgumentNull ( nameof ( source ) ) ;
23
+ return new WithIndexEnumerable < TSource > ( source ) ;
24
+ }
25
+
26
+ /// <summary>
27
+ /// Associates an index to each element of the source array.
28
+ /// </summary>
29
+ /// <typeparam name="TSource">The type of the elements of <c>source</c>.</typeparam>
30
+ /// <param name="source">The source array.</param>
31
+ /// <returns>A sequence of elements paired with their index in the array.</returns>
32
+ [ Pure ]
33
+ public static WithIndexArrayEnumerable < TSource > WithIndex < TSource > (
34
+ [ NotNull ] this TSource [ ] source )
35
+ {
36
+ source . CheckArgumentNull ( nameof ( source ) ) ;
37
+ return new WithIndexArrayEnumerable < TSource > ( source ) ;
38
+ }
39
+
40
+ /// <summary>
41
+ /// Associates an index to each element of the source <see cref="List{T}"/>.
42
+ /// </summary>
43
+ /// <typeparam name="TSource">The type of the elements of <c>source</c>.</typeparam>
44
+ /// <param name="source">The source list.</param>
45
+ /// <returns>A sequence of elements paired with their index in the list.</returns>
46
+ [ Pure ]
47
+ public static WithIndexListEnumerable < TSource > WithIndex < TSource > (
48
+ [ NotNull ] this List < TSource > source )
49
+ {
50
+ source . CheckArgumentNull ( nameof ( source ) ) ;
51
+ return new WithIndexListEnumerable < TSource > ( source ) ;
21
52
}
22
53
23
54
/// <summary>
@@ -28,9 +59,222 @@ public static IEnumerable<IndexedItem<TSource>> WithIndex<TSource>(
28
59
/// <returns>A sequence of elements without their associated indexes.</returns>
29
60
[ Pure ]
30
61
public static IEnumerable < TSource > WithoutIndex < TSource > (
31
- [ NotNull ] this IEnumerable < IndexedItem < TSource > > source )
62
+ [ NotNull ] this IEnumerable < ItemWithIndex < TSource > > source )
32
63
{
33
64
return source . Select ( indexed => indexed . Item ) ;
34
65
}
66
+
67
+ /// <summary>
68
+ /// A sequence of elements associated with their index.
69
+ /// </summary>
70
+ /// <typeparam name="TSource">The type of the elements of the source sequence.</typeparam>
71
+ public struct WithIndexEnumerable < TSource > : IEnumerable < ItemWithIndex < TSource > >
72
+ {
73
+ private readonly IEnumerable < TSource > _source ;
74
+
75
+ internal WithIndexEnumerable ( IEnumerable < TSource > source )
76
+ {
77
+ _source = source ;
78
+ }
79
+
80
+ /// <summary>
81
+ /// Returns an enumerator that iterates through the <see cref="WithIndexEnumerable{TSource}"/>.
82
+ /// </summary>
83
+ /// <returns>An enumerator that iterates through the <see cref="WithIndexEnumerable{TSource}"/>.</returns>
84
+ public Enumerator GetEnumerator ( ) => new Enumerator ( _source . GetEnumerator ( ) ) ;
85
+
86
+ IEnumerator < ItemWithIndex < TSource > > IEnumerable < ItemWithIndex < TSource > > . GetEnumerator ( ) => GetEnumerator ( ) ;
87
+
88
+ IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
89
+
90
+ /// <summary>
91
+ /// Enumerates the elements of a <see cref="WithIndexEnumerable{TSource}"/>.
92
+ /// </summary>
93
+ public struct Enumerator : IEnumerator < ItemWithIndex < TSource > >
94
+ {
95
+ private readonly IEnumerator < TSource > _innerEnumerator ;
96
+ private int _index ;
97
+
98
+ internal Enumerator ( IEnumerator < TSource > inner )
99
+ {
100
+ _innerEnumerator = inner ;
101
+ _index = - 1 ;
102
+ }
103
+
104
+ /// <summary>
105
+ /// Advances the enumerator to the next element of the <see cref="WithIndexEnumerable{TSource}"/>.
106
+ /// </summary>
107
+ /// <returns>true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.</returns>
108
+ public bool MoveNext ( )
109
+ {
110
+ if ( _innerEnumerator . MoveNext ( ) )
111
+ {
112
+ _index ++ ;
113
+ return true ;
114
+ }
115
+
116
+ return false ;
117
+ }
118
+
119
+ void IEnumerator . Reset ( ) => _innerEnumerator . Reset ( ) ;
120
+
121
+ /// <summary>
122
+ /// Releases all resources used by the <see cref="Enumerator"/>.
123
+ /// </summary>
124
+ public void Dispose ( ) => _innerEnumerator . Dispose ( ) ;
125
+
126
+ /// <summary>
127
+ /// Gets the element at the current position of the enumerator.
128
+ /// </summary>
129
+ public ItemWithIndex < TSource > Current => new ItemWithIndex < TSource > ( _innerEnumerator . Current , _index ) ;
130
+
131
+ object IEnumerator . Current => Current ;
132
+ }
133
+ }
134
+
135
+ /// <summary>
136
+ /// A sequence of elements associated with their index, optimized for the case when the underlying collection is an array.
137
+ /// </summary>
138
+ /// <typeparam name="TSource">The type of the elements of the source array.</typeparam>
139
+ public struct WithIndexArrayEnumerable < TSource > : IEnumerable < ItemWithIndex < TSource > >
140
+ {
141
+ private readonly TSource [ ] _array ;
142
+
143
+ internal WithIndexArrayEnumerable ( TSource [ ] array )
144
+ {
145
+ _array = array ;
146
+ }
147
+
148
+ /// <summary>
149
+ /// Returns an enumerator that iterates through the <see cref="WithIndexArrayEnumerable{TSource}"/>.
150
+ /// </summary>
151
+ /// <returns>An enumerator that iterates through the <see cref="WithIndexArrayEnumerable{TSource}"/>.</returns>
152
+ public Enumerator GetEnumerator ( ) => new Enumerator ( _array ) ;
153
+
154
+ IEnumerator < ItemWithIndex < TSource > > IEnumerable < ItemWithIndex < TSource > > . GetEnumerator ( ) => GetEnumerator ( ) ;
155
+
156
+ IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
157
+
158
+ /// <summary>
159
+ /// Enumerates the elements of a <see cref="WithIndexArrayEnumerable{TSource}"/>.
160
+ /// </summary>
161
+ public struct Enumerator : IEnumerator < ItemWithIndex < TSource > >
162
+ {
163
+ private readonly TSource [ ] _array ;
164
+ private int _index ;
165
+
166
+ internal Enumerator ( TSource [ ] array )
167
+ {
168
+ _array = array ;
169
+ _index = - 1 ;
170
+ }
171
+
172
+ /// <summary>
173
+ /// Advances the enumerator to the next element of the <see cref="WithIndexArrayEnumerable{TSource}"/>.
174
+ /// </summary>
175
+ /// <returns>true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.</returns>
176
+ public bool MoveNext ( )
177
+ {
178
+ if ( _index + 1 < _array . Length )
179
+ {
180
+ _index ++ ;
181
+ return true ;
182
+ }
183
+
184
+ return false ;
185
+ }
186
+
187
+ void IEnumerator . Reset ( )
188
+ {
189
+ _index = - 1 ;
190
+ }
191
+
192
+ /// <summary>
193
+ /// Releases all resources used by the <see cref="Enumerator"/>.
194
+ /// </summary>
195
+ public void Dispose ( )
196
+ {
197
+ }
198
+
199
+ /// <summary>
200
+ /// Gets the element at the current position of the enumerator.
201
+ /// </summary>
202
+ public ItemWithIndex < TSource > Current => new ItemWithIndex < TSource > ( _array [ _index ] , _index ) ;
203
+
204
+ object IEnumerator . Current => throw new NotImplementedException ( ) ;
205
+ }
206
+ }
207
+
208
+ /// <summary>
209
+ /// A sequence of elements associated with their index, optimized for the case when the underlying collection is a <see cref="List{T}"/>.
210
+ /// </summary>
211
+ /// <typeparam name="TSource">The type of the elements of the source list.</typeparam>
212
+ public struct WithIndexListEnumerable < TSource > : IEnumerable < ItemWithIndex < TSource > >
213
+ {
214
+ private readonly List < TSource > _list ;
215
+
216
+ internal WithIndexListEnumerable ( List < TSource > list )
217
+ {
218
+ _list = list ;
219
+ }
220
+
221
+ /// <summary>
222
+ /// Returns an enumerator that iterates through the <see cref="WithIndexListEnumerable{TSource}"/>.
223
+ /// </summary>
224
+ /// <returns>An enumerator that iterates through the <see cref="WithIndexListEnumerable{TSource}"/>.</returns>
225
+ public Enumerator GetEnumerator ( ) => new Enumerator ( _list . GetEnumerator ( ) ) ;
226
+
227
+ IEnumerator < ItemWithIndex < TSource > > IEnumerable < ItemWithIndex < TSource > > . GetEnumerator ( ) => GetEnumerator ( ) ;
228
+
229
+ IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
230
+
231
+ /// <summary>
232
+ /// Enumerates the elements of a <see cref="WithIndexListEnumerable{TSource}"/>.
233
+ /// </summary>
234
+ public struct Enumerator : IEnumerator < ItemWithIndex < TSource > >
235
+ {
236
+ private List < TSource > . Enumerator _inner ;
237
+ private int _index ;
238
+
239
+ internal Enumerator ( List < TSource > . Enumerator inner )
240
+ {
241
+ _inner = inner ;
242
+ _index = - 1 ;
243
+ }
244
+
245
+ /// <summary>
246
+ /// Advances the enumerator to the next element of the <see cref="WithIndexListEnumerable{TSource}"/>.
247
+ /// </summary>
248
+ /// <returns>true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.</returns>
249
+ public bool MoveNext ( )
250
+ {
251
+ if ( _inner . MoveNext ( ) )
252
+ {
253
+ _index ++ ;
254
+ return true ;
255
+ }
256
+
257
+ return false ;
258
+ }
259
+
260
+ void IEnumerator . Reset ( )
261
+ {
262
+ _index = - 1 ;
263
+ ( ( IEnumerator ) _inner ) . Reset ( ) ;
264
+ }
265
+
266
+ /// <summary>
267
+ /// Releases all resources used by the <see cref="Enumerator"/>.
268
+ /// </summary>
269
+ public void Dispose ( ) => _inner . Dispose ( ) ;
270
+
271
+ /// <summary>
272
+ /// Gets the element at the current position of the enumerator.
273
+ /// </summary>
274
+ public ItemWithIndex < TSource > Current => new ItemWithIndex < TSource > ( _inner . Current , _index ) ;
275
+
276
+ object IEnumerator . Current => throw new NotImplementedException ( ) ;
277
+ }
278
+ }
35
279
}
36
280
}
0 commit comments