Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select even/odd elements in IEnumerable<T>? [duplicate]

Possible Duplicate:
Getting odd/even part of a sequence with LINQ
How can I get every nth item from a List<T>?

I'm using HtmlAgilityPack and C# to parse some 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>

Basically, I have these elements, each in their own object, inside of an IEnumerable.

Is there an elegant way to get each N/2 element in the collection. Meaning, skip over each div with class .ruler?

I would need to iterate through the resulting set, so either I copy each found object into a new IEnumerable or just use it inline in a foreach function.

For example:

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

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

Which options would be best, and how can I achieve this elegantly?

like image 540
Only Bolivian Here Avatar asked Jun 29 '12 22:06

Only Bolivian Here


2 Answers

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

The only thing that I do not like about this solution is that it requires iterating the sequence twice if you need both the odds and the evens. If for some reason you must avoid this, you'll have to work harder:

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

Then, the odds are those elements of groups where the Key is false, and the evens are those elements of groups where the Key is true:

var odds = groups[false];
var evens = groups[true];
like image 198
jason Avatar answered Nov 07 '22 16:11

jason


You could just define your own extension method for this purpose:

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;
        }
    }
}
like image 7
Philip Daubmeier Avatar answered Nov 07 '22 16:11

Philip Daubmeier