The magazine of the Melbourne PC User Group

Real Programming with JavaScript —
An Array of Functionality

Trevor Gosbell
 


Trevor Gosbell continues the lesson from
the June edition

In the last issue I sang the praises of JavaScript as an advanced programming language, then proceeded to demonstrate some rather unsophisticated methods of input/output. In hindsight my examples didn't support my argument too well. In this article I will rectify things by having a good hard look at JavaScript arrays.

As I've mentioned previously, arrays are a way of holding related or tabulated values together under one variable name. Individual values are usually accessed using an index with syntax similar to Perl and Python:

To add values to an array:

  myArray[0] = "Tom";
myArray[1] = "Dick";
myArray[2] = "Array";

"Tom", "Dick" and "Array" now occupy the first three positions of the array called myArray.

To retrieve values:

  window.alert( myArray[0] );

This instruction retrieves the value at position 0 (that is, "Tom") and prints it in an alert box.

With that knowledge in hand, let's put together a working example. See Listing 1, below.
 

Listing 1

 
var primeMinisters = new Array();
  primeMinisters = ["Barton",
        "Deakin", "Watson",
        "Reid", "Fisher",
        "Cook", "Hughes",
        "Bruce", "Scullin",
        "Lyons", "Page",
        "Menzies", "Fadden",
        "Curtin", "Forde",
        "Chifley", "Holt",
        "McEwen", "Gorton",
        "McMahon", "Whitlam",
        "Fraser", "Hawke",
        "Keating", "Howard"];

  var selectedPM = window.prompt("Which PM? (1-25)", "");
  window.alert( primeMinisters[ selectedPM ] );


This program is only four lines long. Note that each "line" of code in JavaScript is terminated by a semicolon, so it is possible to break the lines to make them easier for humans to read. Let's go through Listing 1, line-by-line:

     
var primeMinisters = new Array();

This line names a new variable primeMinisters and declares that it is going to hold an array of data.

     
primeMinisters = ["Barton" ... "Howard"];

This list of all of the data values inside square brackets is called an array literal and it is a shorthand way of entering data into an array.
 
It is equivalent to writing a series of 25 lines, like this:

        
primeMinisters[0] = "Barton";
     primeMinisters[1] = "Deakin";
     ...
     primeMinisters[23] = "Keating";
     primeMinisters[24] = "Howard";


To me, the shorthand way is just as easy to read and saves a lot of typing.

     var selectedPM = window.prompt("Which PM? (1-25)", "");

Declare another variable
selectedPM. Pop-up a prompt box (see Figure 1) asking the user "Which PM?" and save the response in selectedPM.

     window.alert( primeMinisters[ selectedPM ] );

Use
selectedPM as an index on the primeMinisters array, and print the selected value in an alert box (see Figure 2).



Figure 1: Mozilla Firefox browser asks "Which PM?"



Figure 2: PM number 25 - John Howard

When the user loads the program into a Web browser, they will be prompted to input a number between 1 and 25. When the user enters a number, the name of that Prime Minister is displayed. So if the user inputs 1, the program should display 'Barton' or for 25 it should display 'Howard'.

But it doesn't. Try it. If you input 1 you'll get 'Deakin' and if you input 25 you'll get 'undefined' (see Figure 3). JavaScript arrays are zero-indexed. That is, the first value in the array has an index of 0 not 1. This means that in the primeMinisters array the 25 values are stored in index positions 0 to 24. So index 1 retrieves the second value ('Deakin') and index 25 retrieves an undefined value because 25 is past the end of the array.
 



Figure 3: Everything out of whack.

Choices When Programming

When programming this we have two choices - we can make the user enter the index value directly (that is, they have the choice of numbers between 0 and 24) or we can accept user input between 1 and 25 and adjust the input value. I favour the latter method because people tend to start counting at 1. So all we have to do is adjust the index value by one in the last line:

    window.alert( primeMinisters[ selectedPM ] - 1 );

With this adjustment in place, everything is as it should be: Howard can be found at 25 (Figures 1 & 2) and Barton at 1.

A Few Hidden Extras

Because
primeMinisters is an array, there are certain extra features available. There are several but for the moment we will look at length, concatenation, sort and join.

How Long Is It?

A JavaScript array can tell you how many elements it has, in this case:

    primeMinisters.length

is equal to 25. The value given by
array.length is always one larger than the biggest index value of the array. We can use this to produce a more informative prompt in our example (see Listing 2).
 

Listing 2

   var primeMinisters = new Array();

   primeMinisters = ["Barton",
       ... as in listing 1 ...
       "Keating", "Howard"];

   var promptMessage = "There are " +
      primeMinisters.length +
      " people who have been Prime Minister\n\n" +
      "\t\tChoose a PM (1-" +
      primeMinisters.length + "):";

   var selectedPM = prompt( promptMessage, "" );

   window.alert( primeMinisters[ selectedPM - 1 ] );

The new third line produces a variable named promptMessage that holds the text: "There are 25 people who have been Prime Minister\n\n\t\tChoose a PM (1-25):". The new line character code \n and the tab character code \t are used to space out the text. All of this is put together using the concatenation operator +. promptMessage is then used in the prompt box (see Figures 4 & 5).
 



Figure 4. The new improved prompt as seen in Firefox.



Figure 5. New but not improved - the prompt in Internet Explorer.


Note to Figure 5: Browsers don't always do what you expect. In this version of Internet Explorer a prompt box can only show two lines of text - with two \n characters our improved prompt runs to three lines but the prompt box doesn't expand to show the extra line. There's nothing wrong with the JavaScript, it's just that the browser doesn't handle it very well.

But why did I bother to use primeMinisters.length rather than just the number 25? Despite all signs to the contrary, John Howard can't go on forever and the chances are that one day I'll have to add "Costello" or "Latham" to the primeMinisters array. When that happens, I won't need to change promptMessage at all - it will automatically update to show more people. If I had "hard-coded" the number 25 into promptMessage then I would have to remember to change it (in two places) every time I updated primeMinisters. And I can guarantee I would forget. Using primeMinisters.length in this way is good programming practice.

What if ... ?

So let's look at this scenario:

    morePrimeMinisters = [ "Costello", "Latham" ];

If this hypothetical situation came to pass, how would we adjust our original primeMinisters array? Simply concatenate
morePrimeMinisters to the end of primeMinisters as in Listing 3.
 

Listing 3

   var primeMinisters = new Array();

      primeMinisters = ["Barton",
      ... as in listing 1 ...
      "Keating", "Howard"];

 var morePrimeMinisters = new Array("Costello", "Latham");

 primeMinisters = primeMinisters.concat( morePrimeMinisters );

 var promptMessage = "There are " +
    primeMinisters.length +
    " people who have been Prime Minister\n\n" +
    "\t\tChoose a PM (1-" +
    primeMinisters.length + "):";

  var selectedPM = prompt( promptMessage, "" );

  window.alert( primeMinisters[ selectedPM - 1 ] );

Listing 3 is mostly familiar, except for the third and fourth lines:

   var morePrimeMinisters = new Array("Costello", "Latham");

This is not an array literal, rather it is yet another way of populating an array - a shorthand to the shorthand method.

   primeMinisters = primeMinisters.concat( morePrimeMinisters );

Concatenate the two extra "prime ministers" onto the end of the existing list and put the new array back into the
primeMinisters variable. There are now 27 elements in the array.

Notice that the complicated technique for building promptMessage remains unchanged but the prompt (see Figure 6) now talks about 27 prime ministers. Clearly it was far more elegant to put in that extra effort earlier. Computers are good at keeping track of all that minor (and not-so-minor) detail - you just need to let them do it.
 



Figure 6. A hypothetical - 27 Prime Ministers
from which to choose.



Figure 7. The 27th Prime Minister of Australia?

Get This Join(t) Sort(ed)

Let's say we're not interested in the chronological order of prime ministers. Then we can sort them alphabetically (see Listing 4). Ignoring our previous hypothetical, this program prints the full list of 25 prime ministers firstly in chronological order then sorted into alphabetical order.
 

Listing 4

   var primeMinisters = new Array();

   primeMinisters = ["Barton",
       ... as in listing 1 ...
       "Keating", "Howard"];

   window.alert( primeMinisters.join(", ") );

   primeMinisters.sort();

   window.alert( primeMinisters.join("\n") );

Note the use of
primeMinisters.join() which reduces the list to a character string with each value separated by whatever character string is passed - a quick and handy way of showing everything in the array. In the first alert box (see Figure 7 above), the prime ministers are joined by commas and in the second by new line characters. The primeMinisters.sort() method changes the order of values in primeMinisters itself, as shown by the second alert box (see Figure 8).

Wrap Up

JavaScript has sophisticated array handling equal to any other modern scripting language. In this article we covered:
  • three methods of putting stuff into an array,

  • using an index to get stuff out of an array,

  • getting the length of an array,

  • concatenating arrays,

  • joining array elements, and

  • sorting arrays.
Next time we'll make a hash of it.

Code examples in this article are available from the author's Web page at: http://member.melbpc.org.au/~tgosbell/.



Figure 9. All PMs, sorted and
joined by \n.

Reprinted from the July 2004 issue of PC Update, the magazine of Melbourne PC User Group, Australia

[ About Melbourne PC User Group ]