Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obtain all middle elements IEnumerable LINQ

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?

like image 986
enrique7mc Avatar asked Oct 28 '25 10:10

enrique7mc


2 Answers

Since you know the length upfront, you could use Skip and Take, like this:

var res = Y.Skip(1).Take(Y.Length-2);

Of course you need to check that Y.Length is at least 2.

like image 124
Sergey Kalinichenko Avatar answered Oct 30 '25 05:10

Sergey Kalinichenko


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);
    }
}
like image 25
Jon Skeet Avatar answered Oct 30 '25 05:10

Jon Skeet