Let's say I have a sequence.
IEnumerable<int> sequence = GetSequenceFromExpensiveSource();
// sequence now contains: 0,1,2,3,...,999999,1000000
Getting the sequence is not cheap and is dynamically generated, and I want to iterate through it once only.
I want to get 0 - 999999 (i.e. everything but the last element)
I recognize that I could do something like:
sequence.Take(sequence.Count() - 1);
but that results in two enumerations over the big sequence.
Is there a LINQ construct that lets me do:
sequence.TakeAllButTheLastElement();
It would be helpful if .NET Framework was shipped with extension method like this.
If speed is a requirement, this old school way should be the fastest, even though the code doesn't look as smooth as linq could make it.
This requires that the sequence is an array since it has a fixed length and indexed items.
As an alternative to creating your own method and in a case the elements order is not important, the next will work:
Why not just
.ToList<type>()
on the sequence, then call count and take like you did originally..but since it's been pulled into a list, it shouldnt do an expensive enumeration twice. Right?I would probably do something like this:
This is one iteration with a check that it isn't the last one for each time though.
A slight expansion on Joren's elegant solution:
Where shrink implements a simple count forward to drop the first
left
many elements and the same discarded buffer to drop the lastright
many elements.