Skip to content

Commit 4126e50

Browse files
committed
Add missing Enumerable methods for .NET Standard 2.1.
1 parent 61aaabe commit 4126e50

File tree

1 file changed

+113
-1
lines changed

1 file changed

+113
-1
lines changed

mcs/class/referencesource/System.Core/System/Linq/Enumerable.cs

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2777,7 +2777,7 @@ public string Empty
27772777
get
27782778
{
27792779
#if UNITY_AOT
2780-
return SR.EmptyEnumerable;
2780+
return SR.EmptyEnumerable;
27812781
#else
27822782
return Strings.EmptyEnumerable;
27832783
#endif
@@ -2878,5 +2878,117 @@ internal static partial class Error
28782878

28792879
internal static Exception NotSupported() => new NotSupportedException();
28802880
}
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+
}
28812993
#endif
28822994
}

0 commit comments

Comments
 (0)