Выберите четные/нечетные элементы в IEnumerable <T>?

Возможный дубликат:
Получение нечетной/четной части последовательности с LINQ
Как я могу получить каждый n-й элемент из списка <T> ?

Я использую HtmlAgilityPack и С# для анализа некоторого HTML.

<div id="post-8266">
<div class="ruler"> </div>
<div id="post-8266">
<div class="ruler"> </div>
<div id="post-8266">
<div class="ruler"> </div>
<div id="post-8266">
<div class="ruler"> </div>

В принципе, у меня есть эти элементы, каждый в своем собственном объекте, внутри IEnumerable.

Есть ли элегантный способ получить каждый элемент N/2 в коллекции. Смысл, пропустите каждый div с классом .ruler?

Мне нужно будет проходить через результирующий набор, так что либо я копирую каждый найденный объект в новый IEnumerable, либо просто использую его inline в функции foreach.

Например:

//Copying resulting set to new IEnumerable<T>:
var odds = elements.SelectOdds();

//Using it inline for my usage:
foreach (var x in elements.SelectOdds())
{   
}

Какие варианты были бы лучше, и как я могу достичь этого элегантно?

Ответы

Ответ 1

var odds = sequence.Where((item, index) => index % 2 != 0);
var evens = sequence.Where((item, index) => index % 2 == 0);

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

var groups = sequence.Select((item, index) => new { Item = item, Index = index })
                     .GroupBy(x => x.Index % 2 == 0)
                     .ToDictionary(g => g.Key, g => g);

Тогда коэффициенты - это те элементы groups, где Key - false, а evens - это те элементы groups, где Key - true:

var odds = groups[false];
var evens = groups[true];

Ответ 2

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

public static class LinqExtensions
{
    public static IEnumerable<T> SelectOdds<T>(this IEnumerable<T> enumerable)
    {
        bool odd = false;

        foreach (var item in enumerable)
        {
            if (odd)
                yield return item;

            odd = !odd;
        }
    }
}