Category Archives: LINQ

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