Get all middle elements of IEnumerable LINQ
I have an array Y containing int, for example [1 3 2 0 9 8 2], I want to select all elements except the 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)
Is there a better way to do this?
+3
source to share
2 answers
dasblinkenlight's approach is probably the best if you are happy to limit yourself to collections where you know the length in advance. If you don't, you can 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;
}
}
}
Then you used:
var elements = original.Skip(1).SkipEnd(1);
The above implementation contains its own circular buffer, but you can easily use Queue<T>
it if you like. 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);
}
}
+2
source to share