I have an array Y with containing ints e.g [1 3 2 0 9 8 2], I want to select all the elements except first and last [3, 2, 0 , 9, 8, 2] to use them in further operations. This is my current approach:
Y.Where((i, x) => i != 0 && i != Y.Length - 1)
There is a better way to do this?
dasblinkenlight's approach is probably the best if you're happy to restrict yourself to collections where you know the length beforehand. If you don't, you might want to add an extension method like this (untested):
public static IEnumerable<T> SkipEnd<T>(this IEnumerable<T> source,
int countToSkip)
{
// TODO: Validation
T[] buffer = new T[countToSkip];
int index = 0;
bool returning = false;
foreach (var item in source)
{
if (returning)
{
yield return buffer[index];
}
buffer[index] = item;
index++;
if (index == countToSkip)
{
index = 0;
returning = true;
}
}
}
You'd then use:
var elements = original.Skip(1).SkipEnd(1);
The implementation above contains its own circular buffer, but you could easily use a Queue<T>
instead if you wanted to. For example:
public static IEnumerable<T> SkipEnd<T>(this IEnumerable<T> source,
int countToSkip)
{
// TODO: Validation
Queue<T> queue = new Queue<T>(countToSkip);
foreach (var item in source)
{
if (queue.Count == countToSkip)
{
yield return queue.Dequeue();
}
queue.Enqueue(item);
}
}
See more on this question at Stackoverflow