LINQ: Each iterator with exposed Index

The Each Iterator

I’ve noticed a really handy extension method crop-up in several open source tools and frameworks that I’ve worked with; the each iterator. This simple extension method allows an action to be performed on each element of a source collection. The action is specified by providing a lambda expression as a parameter to the Each method. This allows for a more succinct way of expressing an iteration, where previous to .NET 3.5, a foreach statement may have been used.

This:

foreach( var item in collection)
{
    item.DoSomething()
}

becomes:

collection.Each(item=>item.DoSomething())

A simple implementation of this can be found in the Source for FubuMVC:

[DebuggerStepThrough]
public static IEnumerable<T> Each<T>(this IEnumerable<T> values, Action<T> eachAction)
{
    foreach( var item in values )
    {
        eachAction(item);
    }

    return values;
}

The need for an index

For a recent piece of work, I wanted to expose the current elements index. The index could then be used, for example, for alternating row styles like this:

<%  form.Items.Each((item, i) => 

{%>

     <tr class='hidden <%= i % 2 == 0 ? "item" : "altitem" %>'>

          <td class="first">&nbsp;</td>

           <td><%= item.SomeField %></td>

           <td><%= expense.SomeValue %></td>

      </tr>

 <%}%>

The syntax used for the Each overload is similar to the overload for select() in System.Linq.

The implementation

Here is the implementation I’m currently using to achieve this:

[DebuggerStepThrough]
public static IEnumerable<T> Each<T>(this IEnumerable<T> values, Action<T, int> eachAction)
{
    return values.Select((vals, i) => new { Values = vals, Index = i })
        .Each(x => eachAction(x.Values, x.Index))
        .Select(x => x.Values);
}

This method uses the overload of select() to return the original collection with an index for each item (projected into an anonymous type). This anonymous type provides us the index we need to perform the provided action. We then iterate over this new collection of anonymous types, to perform the action; we can use the previously show Each implementation (from Fubu) to do this. Finally we select the original values whose elements have now had the action performed on them, and return them.

 

Hopefully someone else may find this useful too!

Advertisements

About craigcav

Craig Cavalier works as a Software Developer for Liquid Frameworks in Houston Tx, developing field ticketing and job management solutions for industrial field service companies.

Posted on September 21, 2009, in LINQ and tagged , . Bookmark the permalink. 6 Comments.

  1. Eric Lippert discusses the issues surrounding a ForEach extension method here:

    http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

    Consider his points carefully, especially the one about lambdas introducing closure semantics, before deciding that an extension method is better than a language construct in this case.

    • Hi Bryan,

      Thanks for your comments, and for the link – there are some very good points raised, particularly in regard to side effects of functions.

      I’ll certainly take this into consideration.

  2. Actually Craig, I’d say that this solution should really be resolved in your Form mapper classes. Whichever class implements the code to perform the function: DataMapper(Data) => DataForm.
    You want an MVC View to implement as little logic as possible.
    Leaving you with just following:

    {%>

    <tr class="”>

     

    Removing the logic from the View leaves you with something that you can also test.

    Have no idea why this occurred to me in January for a post from October. 🙂

  3. Hi Chris, thanks for your comment.

    You are, of course, right with your sentiment – the less logic in the view, the better. In this case, the view model you have proposed (such that an item has a CssClass) is one way to remove this “complexity” from the view. The “Each” extension method I showed in this post could also be put to good use to make for an easy way to populate your suggested view model (although the pre-build in Select overload may be a better option for this).

    The only thing that doesn’t sit right with me about having the CSS class populated on the view model is that I actually think the styling SHOULD exist within the view itself – that is the views responsibility. It is also beneficial if the styling is not set in compiled code – I don’t want to have to rebuild my solution to change some CSS, or to change my page layout. I think a better alternative would be to use an existing solution such as the Mvccontrib grid (or there are other very good mvc grids available too). This way, the alternating styles are defined in the view, and the “grid builder” itself is in a separate, well tested assembly.

    In any case, I’m hoping this extension method will prove useful outside of the example I provided.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: