We all know that Skip()
can omit records that are not needed at the start of a collection.
But is there a way to Skip()
records at the end of a collection?
How do you not take the last record in a collection?
Or do you have to do it via Take()
ie, the below code,
var collection = MyCollection
var listCount = collection.Count();
var takeList = collection.Take(listCount - 1);
Is this the only way exclude the last record in a collection?
With enumerator you can efficiently delay yielding by one enumeration.
public static IEnumerable<T> WithoutLast<T>(this IEnumerable<T> source)
{
using (IEnumerator<T> e = source.GetEnumerator())
{
if (e.MoveNext() == false) yield break;
var current = e.Current;
while (e.MoveNext())
{
yield return current;
current = e.Current;
}
}
}
Usage
var items = new int[] {};
items.WithoutLast(); // returns empty
var items = new int[] { 1 };
items.WithoutLast(); // returns empty
var items = new int[] { 1, 2 };
items.WithoutLast(); // returns { 1 }
var items = new int[] { 1, 2, 3 };
items.WithoutLast(); // returns { 1, 2 }
A slightly different version of Henrik Hansen's answer:
static public IEnumerable<TSource> SkipLast<TSource>(
this IEnumerable<TSource> source, int count)
{
if (count < 0) count = 0;
var queue = new Queue<TSource>(count + 1);
foreach (TSource item in source)
{
queue.Enqueue(item);
if (queue.Count > count) yield return queue.Dequeue();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With