There is the enumerable extension method
Take<TSource>(
IEnumerable<TSource> source,
int count
)
which takes the first count
elements from the start.
Is there a way to take the elements from the end? or even better a way to take the elements from an offset to the end?
Thanks
finiteList.Reverse().Take(count).Reverse();
or
finiteList.Skip(finiteList.Count() - count)
There is some overhead in doing this so a custom method would be better.
Update: A custom method
public static class EnumerableExtensions
{
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int count)
{
if (source == null) throw new ArgumentNullException("source");
if (count < 0) throw new ArgumentOutOfRangeException("count");
if (count == 0) yield break;
var queue = new Queue<T>(count);
foreach (var t in source)
{
if (queue.Count == count) queue.Dequeue();
queue.Enqueue(t);
}
foreach (var t in queue)
yield return t;
}
}
Update: Changed the code a littlebit with ideas from dtb´s answer :-)
Comment to Bear: Look at this example:
var lastFive = Enumerable.Range(1, 10).TakeLast(5);
var lastFive2 = Enumerable.Range(1, 10).TakeLast2(5); //Bear´s way
Queue<int> q = (Queue<int>)lastFive2;
q.Dequeue();
//Is lastFive2 still last five? no...
You could potentially change the values of lastFive2
and therefore that approach can be unsafe or at least it´s not the functional way.
To Bear:
What I meant about safe is this:
var lastFive2 = Enumerable.Range(1, 10).TakeLast2(5); //Bear´s way
//some = Some method which you don't control - it could be from another assembly which represents a crazy plugin etc.
some(lastFive2);
//Now what?
In these cases you would have to make a copy to be sure. But in most cases your way would be fine - and a little bit more efficient than this so +1 :)
An idea is to use a queue which only have internal Enqueue etc.
MoreLINQ provides a TakeLast extension method:
var last10 = finiteList.TakeLast(10);
To take the elements from an offset to the end, Enumerable.Skip should do the trick:
var allFromOffsetToEnd = finiteList.Skip(offset);
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