2014-11-12 6 views
3

У меня есть массив Y с содержащими ints, например [1 3 2 0 9 8 2], я хочу выбрать все элементы, кроме первого и последнего [3, 2, 0, 9, 8, 2], чтобы использовать их в дальнейших операциях. Это мой текущий подход:Получить все средние элементы IEnumerable LINQ

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

Существует лучший способ сделать это?

ответ

4

Поскольку вы знаете длину авансовый, вы могли бы использовать Skip и Take, как это:

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

Конечно, вы должны проверить, что Y.Length является подход, по крайней мере 2.

+0

Эта версия будет изящно возвращать пустое перечисление без каких-либо специальных проверок – thewyzard

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