Choosing from Alternative Ways to Code

In any programming language there are usually alternative ways to produce any given result. The more complex the problem the more alternatives there are. A task doesn't need to be all that complex in order for there to be several alternatives though. Even simple things can often be done in more than one way.

As a relatively simple example let's look at several different ways that we can insert the numbers 1 through 10 into an array. Possibly the most obvious way would be:

``myarray = [];for (i = 1; i <= 10; i++) {  myarray[i] = i;}``

The problem with this code is that JavaScript arrays start from zero and that code doesn't load anything into myarray[0] which means that at the end of the loop the array contains [undefined,1,2,3,4,5,6,7,8,9,10] which is most probably not what we want.

Now we could change that 1 in the code into a 0 in order to load the number 0 into the start of the array instead of leaving it undefined but that too wouldn't give the desired result of an array containing just the numbers 1 through 10. At least having the loop start from zero means that we start loading the array from the beginning.

There are two relatively simple ways we can change the loop so that it loads the numbers into the first ten positions in the loop depending on whether we want i to represent the position in the array or the number we are loading. Here's how we'd use it as the position in the array:

``myarray = [];for (i = 0; i < 10; i++) {  myarray[i] = i+1;}``

Here's how we'd use it as the number to load:

``myarray = [];for (i = 1; i <= 10; i++) {  myarray[i-1] = i;}``

The problem with either of those approaches is that in each case we need to do two calculations using i instead of the one we had in the original loop. The first variant needs to add one to the variable twice each pass through the loop. The second variant both adds and subtracts one each time through the loop. If we were to make the number to be loaded and the position to load it into separate variables things would be no better as we'd still need to change both variables each time around the loop. The code in either of these versions would be made even more complicated if we needed to allow for there already being entries stored in the array where we want to add the new values to the end of what is already there without overwriting the existing entries.

There is a way to modify our original loop so that it loads into the array from the start rather than leaving any entries undefined and that is to use the Array.push() method which adds the specified value onto the end of the array.

``myarray = [];for (i = 1; i <= 10; i++) {  myarray.push(i);}``

This gives us a version of the code that loads just the numbers one through ten into the array without leaving any undefined elements on the front of the array and which also only needs to do one calculation using i each time around the loop. This is therefore the simplest and most efficient way to add the numbers into the array. Of course we haven't considered all the possible ways that we could have coded this but the alternatives not shown here would all involve using even more code to achieve this result.

Having chosen this particular solution we can make a minor change that will allow any specified range of numbers to be inserted into an array without leaving any undefined entries. The following code adds an addNumbers method to all our arrays that will add a range of numbers to the end of the array simply by passing the first and last number to be added.

``Array.prototype.addNumbers - function(a,b) {"use strict";var i;for (i = a; i <= b; i++) {  myarray.push(i);}}``

This gives us a simple way to be able to add a range of numbers to the end of any array where we need only worry about the numbers that are to be added and not have to concern ourselves with calculating what entries in the array have already been used. Not only does adding this method reduce the code needed to solve the original problem to:

``myarray = [];myarray.addNumbers(1,10);``

Should the requirement be to load the numbers one through ten and twenty five through fifty then we can simply add a single statement in order to satisfy the additional requirement like this:

``myarray = [];myarray.addNumbers(1,10);myarray.addNumbers(25,50);``

This clearly demonstrates that we have selected the best of the solutions we have considered since to change any of the other alternatives to cater for this additional requirement would mean we'd have to modify the code we already have rather than simply adding one extra statement.

When you apply this approach to more complex tasks you may overlook some of the alternatives that would lead to simpler and easier to maintain code but at least you will know that the alternative you have used is the best of those that you know of at the time. Should an even better way occur to you afterwards then you can incorporate that into the next version of the script.

This article written by Stephen Chapman, Felgall Pty Ltd.