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


Since you know the length upwards, you can use Skip

and Take

, for example:

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

      



Of course, you need to check that there are Y.Length

at least 2.

+4


source


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







All Articles