Refactoring a for loop using Linq

Do the smallest thing that works

We do the smallest thing that works first so that we can reach the solution quicker. With good test we know we can refactor to our hearts content to make the code cleaner, readable and above a joy to work with.

The Mess

I had the following code below…….

private int CalculateRemainingMoves()
{
char[] markers = grid.ToCharArray();
int count = 0;

foreach (var marker in markers)
{
if (IsValidMarker(marker)
{
count += 1;
}
}

return count;
}
}

This was the quickest code that I wanted to write to get my test to pass. A simple method that calculates the remaining moves on a grid.

Smell

This code bothered me.
– For one it has too many lines
– The temporary ‘count’ variable is used in 3 places… yuc
– It hurts my soul

First steps

The first temporary variables ‘markers’ doesn’t bother me too much as it indicates what the individual grid elements are, so I’ll keep that.

The first action to take is to take away the ‘count’ temporary variable.

Linq to the rescue (not that other link from that legend of a game)

The markers data type being a char, we can use a handy linq method called Count, which unsurprisingly counts the number of elements in the collection. However we didn’t just want to count the number of elements, we wanted to count the elements which were valid i.e ‘X’ or ‘O’ in our Tic Tac Toe game.
Luckily by passing our method ‘IsValidMarker’, the count method will call the specified method on each element of the collection and only add them to the count if they valid. How neat!

This drastically reduces the code.

Our final code looks like this….

private int CalculateRemainingMoves()
{
var markers = grid.ToCharArray();

return markers.Count(IsValidMarker);
}

Now doesn’t that look nicer..

hmm on second thought I might remove that temporary variable…. šŸ™‚

UPDATE!

I refactored the code again, couldn’t help myself.

private int CalculateRemainingMoves()

{

return (grid .Length – grid.Count(IsValidMarker());

}

 

Ced

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

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