Linq пропустить сначала где (linq к объектам) - PullRequest
4 голосов
/ 15 марта 2011

Мне нужно пропустить первый элемент, который соответствует предикату, как запрос linq.Насколько я могу сказать, лучшее, что я могу сделать, это что-то вроде этого:

var list = new [] {1,2,3,4,5,6,7,8,9};
var skippedFirstOdd = false;
var skipFirstEvenNumber = list.SkipWhile(number => 
                                         {
                                             if(number % 2 != 0)
                                             {
                                                 skippedFirst = true;
                                                 return true;
                                             }
                                             else
                                             {
                                                 return false;
                                             }
                                         });

Что работает (я думаю), но не очень элегантно.Есть ли более чистый способ добиться этого?

1 Ответ

7 голосов
/ 15 марта 2011

Вы можете написать метод расширения блока итератора:

public static IEnumerable<T> SkipFirstMatching<T>
      (this IEnumerable<T> source, Func<T, bool> predicate)
{        
    if (source == null)
        throw new ArgumentNullException("source");

    if (predicate == null)
        throw new ArgumentNullException("predicate");

    return SkipFirstMatchingCore(source, predicate);
}

private static IEnumerable<T> SkipFirstMatchingCore<T>
      (IEnumerable<T> source, Func<T, bool> predicate)
{            
    bool itemToSkipSeen = false;

    foreach (T item in source)
    {
        if (!itemToSkipSeen && predicate(item))
            itemToSkipSeen = true;

        else yield return item;
    }
}

И используйте его как:

var list = new [] { 1,2,3,4,5,6,7,8,9 };
var skipFirstEvenNumber = list.SkipFirstMatching(i => i % 2 == 0);

Кстати, ваш текущий код не выглядит верным вообще. Переменная называется skipFirstEvenNumber, но в запросе пропускаются нечетные числа. Во-вторых, вы, кажется, пытаетесь использовать побочный эффект, чтобы заставить запрос работать, но вы только устанавливаете переменную флага, а не читаете ее. Следовательно, ваш текущий код должен работать так же, как обычный SkipWhile.

РЕДАКТИРОВАТЬ : Сделана проверка аргументов нетерпеливым.

...