获取IEnumerable LINQ的所有中间元素

时间:2014-11-12 16:49:20

标签: linq ienumerable

我有一个包含整数的数组Y,例如[1 3 2 0 9 8 2],我想选择除了第一个和最后一个[3,2,0,9,8,2]之外的所有元素来使用它们进一步的行动 这是我目前的做法:

Y.Where((i, x) => i != 0 && i != Y.Length - 1)

有更好的方法吗?

2 个答案:

答案 0 :(得分:5)

由于您事先知道长度,因此可以使用SkipTake,如下所示:

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

当然,您需要检查Y.Length是否至少为2.

答案 1 :(得分:2)

如果您乐意将自己限制在事先知道长度的集合中,那么dasblinkenlight的方法可能是最好的方法。如果你没有,你可能想要添加这样的扩展方法(未经测试):

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;
        }
    }
}

然后您使用:

var elements = original.Skip(1).SkipEnd(1);

上面的实现包含自己的循环缓冲区,但如果您愿意,可以轻松使用Queue<T>。例如:

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);
    }
}