@@ -157,5 +157,41 @@ public static bool IsPopulated<T>(this IEnumerable<T> source)
157157 /// </returns>
158158 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
159159 public static bool IsPopulatedSafe < T > ( this IEnumerable < T > source ) => source != null && source . IsPopulated ( ) ;
160+
161+ /// <summary>
162+ /// Gets the element at the specified index from the end (1-based).
163+ /// For example, FromEnd(1) returns the last item, FromEnd(2) returns second-to-last.
164+ /// </summary>
165+ public static T FromEnd < T > ( this IEnumerable < T > source , int reverseIndex )
166+ {
167+ if ( source is SwiftList < T > swift )
168+ return swift . FromEnd ( reverseIndex ) ;
169+
170+ // fallback for generic IEnumerable
171+ var buffer = new List < T > ( source ) ;
172+ return buffer . FromEnd ( reverseIndex ) ;
173+ }
174+
175+ /// <summary>
176+ /// Gets the element at the specified index from the end (1-based) from SwiftList.
177+ /// </summary>
178+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
179+ public static T FromEnd < T > ( this SwiftList < T > list , int reverseIndex )
180+ {
181+ if ( reverseIndex <= 0 || reverseIndex > list . Count )
182+ throw new ArgumentOutOfRangeException ( nameof ( reverseIndex ) ) ;
183+ return list [ list . Count - reverseIndex ] ;
184+ }
185+
186+ /// <summary>
187+ /// Returns the last item in the sequence.
188+ /// </summary>
189+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
190+ public static T Last < T > ( this IEnumerable < T > source ) => source . FromEnd ( 1 ) ;
191+
192+ /// <summary>
193+ /// Returns the second-to-last item in the sequence.
194+ /// </summary>
195+ public static T SecondToLast < T > ( this IEnumerable < T > source ) => source . FromEnd ( 2 ) ;
160196 }
161197}
0 commit comments