Ben McCallum's Blog

Dissecting ASP.NET MVC3, CSS3, HTML5, jQuery and a whole lot of other things ending with numbers…

a foreach loop with an index thanks to LINQ

I’ve been spending a lot of time using ASP.NET MVC3 and the new Razor syntax. One of the newer things for me is to throw away the from the days of WebForms and throw the foreach loop straight into View template markup. Recently I needed to maintain an index of the current item when iterating through my Model so that I could add a class in the markup to every third item in the IEnumerable.

Sure, you could use a simple for loop like so:

@model IEnumerable

<ul>
for (int i=1; i<=Model.Count(); i++)
{
<li @if (i%3 == 0) { <text>class=”last” </text>}>
Movie Name: @Model.ElementAt(i).Title
<li>
}
</ul>

But the markup isn’t as readable and it isn’t completely clear that you are iterating over the Model elements until you look within the for loop. You are throwing away all of the advantages of the foreach syntax simply to gain the index of the element. Surely there’s is a better way you ask? Luckily there is thanks to the power of LINQ:


@model IEnumerable

<ul>
@foreach (var movie in Model.Select((x, i) => new { Data = x, Index = i }))
{
<li @if ((movie.Index + 1) % 3 == 0) { <text>class=”last” </text>}>
Movie Name: @movie.Data.title
</li>
}
</ul>

Now you can access the index via movie.Index and the strongly-typed Movie object via movie.Data. Plus the code is much more readable and consistent with the more commonly used foreach syntax.

Happy coding :)

About these ads

Single Post Navigation

3 thoughts on “a foreach loop with an index thanks to LINQ

  1. Couldn’t you also have just cast to a List right there at the end and gotten it’s position there?

    • benmccallum on said:

      I’m not sure exactly what you mean but I take it your saying use List as the model type? Or to simply cast Model like foreach (var item in Model.ToList())
      In that case in the body of the foreach you could infact do something like Model.IndexOf(item) but that requires an O(n) lookup every time you get to a new item making the whole loop O(n^2).

      The problem is you still can’t do item.Index and get the index of the current item as you’re iterating over the items in the enumerable type. Instead you can use linq to create a list of object that has the index as well as the value. This required you to iterate over the list 2 times making it O(2n) but that of course is still considered O(n).

      Let me know if you are still confused or if I haven’t got your point. Cheers

  2. hey thankx man…it really helped me..
    :)

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

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: