@@ -2777,7 +2777,7 @@ public string Empty
2777
2777
get
2778
2778
{
2779
2779
#if UNITY_AOT
2780
- return SR . EmptyEnumerable ;
2780
+ return SR . EmptyEnumerable ;
2781
2781
#else
2782
2782
return Strings . EmptyEnumerable ;
2783
2783
#endif
@@ -2878,5 +2878,117 @@ internal static partial class Error
2878
2878
2879
2879
internal static Exception NotSupported ( ) => new NotSupportedException ( ) ;
2880
2880
}
2881
+
2882
+ public static partial class Enumerable
2883
+ {
2884
+ public static IEnumerable < TSource > SkipLast < TSource > ( this IEnumerable < TSource > source , int count )
2885
+ {
2886
+ if ( source == null )
2887
+ {
2888
+ throw Error . ArgumentNull ( nameof ( source ) ) ;
2889
+ }
2890
+
2891
+ if ( count <= 0 )
2892
+ {
2893
+ return source . Skip ( 0 ) ;
2894
+ }
2895
+
2896
+ return SkipLastIterator ( source , count ) ;
2897
+ }
2898
+
2899
+ private static IEnumerable < TSource > SkipLastIterator < TSource > ( IEnumerable < TSource > source , int count )
2900
+ {
2901
+ var queue = new Queue < TSource > ( ) ;
2902
+
2903
+ using ( IEnumerator < TSource > e = source . GetEnumerator ( ) )
2904
+ {
2905
+ while ( e . MoveNext ( ) )
2906
+ {
2907
+ if ( queue . Count == count )
2908
+ {
2909
+ do
2910
+ {
2911
+ yield return queue . Dequeue ( ) ;
2912
+ queue . Enqueue ( e . Current ) ;
2913
+ }
2914
+ while ( e . MoveNext ( ) ) ;
2915
+ break ;
2916
+ }
2917
+ else
2918
+ {
2919
+ queue . Enqueue ( e . Current ) ;
2920
+ }
2921
+ }
2922
+ }
2923
+ }
2924
+
2925
+ public static IEnumerable < TSource > TakeLast < TSource > ( this IEnumerable < TSource > source , int count )
2926
+ {
2927
+ if ( source == null )
2928
+ {
2929
+ throw Error . ArgumentNull ( nameof ( source ) ) ;
2930
+ }
2931
+
2932
+ if ( count <= 0 )
2933
+ {
2934
+ return EmptyEnumerable < TSource > . Instance ;
2935
+ }
2936
+
2937
+ return TakeLastIterator ( source , count ) ;
2938
+ }
2939
+
2940
+ private static IEnumerable < TSource > TakeLastIterator < TSource > ( IEnumerable < TSource > source , int count )
2941
+ {
2942
+ Queue < TSource > queue ;
2943
+
2944
+ using ( IEnumerator < TSource > e = source . GetEnumerator ( ) )
2945
+ {
2946
+ if ( ! e . MoveNext ( ) )
2947
+ {
2948
+ yield break ;
2949
+ }
2950
+
2951
+ queue = new Queue < TSource > ( ) ;
2952
+ queue . Enqueue ( e . Current ) ;
2953
+
2954
+ while ( e . MoveNext ( ) )
2955
+ {
2956
+ if ( queue . Count < count )
2957
+ {
2958
+ queue . Enqueue ( e . Current ) ;
2959
+ }
2960
+ else
2961
+ {
2962
+ do
2963
+ {
2964
+ queue . Dequeue ( ) ;
2965
+ queue . Enqueue ( e . Current ) ;
2966
+ }
2967
+ while ( e . MoveNext ( ) ) ;
2968
+ break ;
2969
+ }
2970
+ }
2971
+ }
2972
+
2973
+ do
2974
+ {
2975
+ yield return queue . Dequeue ( ) ;
2976
+ }
2977
+ while ( queue . Count > 0 ) ;
2978
+ }
2979
+
2980
+ public static HashSet < TSource > ToHashSet < TSource > ( this IEnumerable < TSource > source ) => source . ToHashSet ( comparer : null ) ;
2981
+
2982
+ public static HashSet < TSource > ToHashSet < TSource > ( this IEnumerable < TSource > source , IEqualityComparer < TSource > comparer )
2983
+ {
2984
+ if ( source == null )
2985
+ {
2986
+ throw Error . ArgumentNull ( nameof ( source ) ) ;
2987
+ }
2988
+
2989
+ // Don't pre-allocate based on knowledge of size, as potentially many elements will be dropped.
2990
+ return new HashSet < TSource > ( source , comparer ) ;
2991
+ }
2992
+ }
2881
2993
#endif
2882
2994
}
0 commit comments