Monthly Archives: September 2009

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!

Why share knowledge?

I’ve been watching the Continuous Integration Workshop video that Eric Hexter and Jeffrey Palermo presented and that Headspring Systems kindly made available on their website.  Quite early into this video, Jeffery gives a refreshing perspective providing some insight into why Headspring are happy to share knowledge through mechanisms like OSS, free workshops and blogs.

We want to be working on problems that the industry hasn’t solved.

Jeffery mentions that at Headspring, they make use of many open source projects and that this allows them to focus on solving new problems, and move forward efficiently. This allows them to focus on delivering value to their customers rather than having to spend time re-inventing the wheel.

Having looked into this further, I found the following quote on Headsprings website:

Because so much of our efficiency comes from open-source sharing and re-use of successful code modules, we believe in the power of open source. So much so that we frequently share our own code with other developers; yes, even our competitors

They embrace giving back to the community – presenting the problems that they have solved, such that others may benefit in the same way.

 

I find this attitude very refreshing indeed.

Upgrading a webforms project to an ASP.NET MVC application

In a newly created ASP.NET MVC application, Visual Studio is quite friendly to us, and provides us nice little menus for creating our controllers/views:

The New Project dialog box

This menu does is not provided however, for any existing apps that we may want to migrate to using ASP.NET MVC.

How can we tell Visual Studio to treat this web app as an ASP.NET MVC app? I couldn’t find an immediately obvious way to do this, and it took me more than a simple google search to figure this one out, so here’s what to do:

  1. Unload the web project (right clicking on the project within Visual Studio –> Unload Project)
  2. Find the tag <ProjectTypeGuids>
  3. Add the guid {603c0e0b-db56-11dc-be95-000d561079b0};
  4. Reload the project
  5. The new menus should now be available! (you should probably now go ahead and add the Controllers and Views folders)

 

Hopefully this helps someone else too!

 

*disclaimer* This worked for me, but I place no guarantees that it will work for you too!! If your computer explodes, your cat passes away, or you end up getting a divorce, please don’t blame me!  *disclaimer*