Let\'s say I have a sequence.
IEnumerable sequence = GetSequenceFromExpensiveSource();
// sequence now contains: 0,1,2,3,...,999999,1000000
A slight expansion on Joren's elegant solution:
public static IEnumerable Shrink(this IEnumerable source, int left, int right)
{
int i = 0;
var buffer = new Queue(right + 1);
foreach (T x in source)
{
if (i >= left) // Read past left many elements at the start
{
buffer.Enqueue(x);
if (buffer.Count > right) // Build a buffer to drop right many elements at the end
yield return buffer.Dequeue();
}
else i++;
}
}
public static IEnumerable WithoutLast(this IEnumerable source, int n = 1)
{
return source.Shrink(0, n);
}
public static IEnumerable WithoutFirst(this IEnumerable source, int n = 1)
{
return source.Shrink(n, 0);
}
Where shrink implements a simple count forward to drop the first left many elements and the same discarded buffer to drop the last right many elements.