Skip to Content

JavaScript & Complex Data - Arrays

Often times, we need to store more than a simple value. For instance, we might need to store contact information about our friends. In this case a simple list just isn't up to the job. However, an array can still be used to store complex data. In fact there's a number of ways to do so...

Arrays are wonderful tools that allow us to do so much with them. But arrays are often the misunderstood child of JavaScript. So, let's spend some time talking about how arrays can be used. No, I don't mean that we can use them to store our grocery list, or form objects (though it does these tasks fantastically). I mean let's get fancy with them. Let's talk about multi-dimensional arrays, or associative arrays, or creative ways to use an array.

But, let's start with the easy stuff. If you know what an array is (and anyone who does any sort of programming needs to know this pretty quickly), then you know that a simple array is like a one column spreadsheet. We use the row number to indicate which element of the array we want to refer to. JavaScript is one of those languages that use zero-based arrays - that means the first element is index zero. (If you don't understand why, think of the index as an offset from the memory point where the array starts. An index of zero means don't use an offset, whereas an index of 3 means to move the offset 3 locations from the starting point, and give us the next element from that point - which is the 4th element in the array.)

So, if we do a quick array listing our friends, we might have something like this:

var myfriends = new Array("Bob", "Jane", "Dave", "Joanne");

But there's a small problem here. What if we wanted to store contact information for our friends? Well, one answer could be to use related arrays:

var myfriends = new Array("Bob", "Jane", "Dave", "Joanne");
var phoneNumbers = new Array("555-1111", "555-2222", "555-3333", "555-4444");

Then we could say that if we are refering to our friend at index 1 (Jane), then the same index will get us the correct phone number. This approach does work, but can become a pain if we have many properties, or very large arrays. Is there another way? Yep, use multi-dimensional arrays.

Now, a multidimensional array is nothing more than an array that can have one element represent many other elements. A spreadsheet or table is a great example of a two dimensional array. But the number of dimensions you can have doesn't have any real limit (other than processing speed and memory). In practice though you very rarely run into situations that absolutely need 3 or more dimensions, and when you do, there's other methods that work better.

So, lets' see how we might store a friend using a two diminsion array:

var myFriends = new Array();
myFriends[0][0] = "Bob";
myFriends[0][1] = "555-1111";

Here we are saying take the first index of the array (the first [0]), and then assign values to the second index (the second [0], and the [1]). Think of the first index as the "friend index", and the second index as the "property index". But be careful here - it doesn't really matter which order these two indexes are used, other than once you set the order, you must ALWAYS use that order for the life of that array. If you don't, you'll start retrieving or setting the wrong data. (i.e. row 5 and column 3 of a table is NOT the same as row 3 and column 5 of the same table).

To deal with multi-dimensional arrays, you simply keep adding on indexes. In theory, you could see a reference like this:

myArray[2][4][2][3][6][1][8][6][1] = "some value";

But that would be UGLY to try to maintain. Is there another way to look at complex data? Yep, we could use an array as structured data. So a friend might then be represented like this:

var bob = new Array();
bob[0] = "Bob";
bob[1] = "Smith";
bob[2] = "555-1111";
bob[3] = "123 Main Street";
myFirends[myFirends.length] = bob;

So, we are setting up a structure, and then assuming that in that structure a particular index means something specific. In this example, index 2 is a phone number.

But what's that last line doing? Yep, you got it, we're going to store our data structure (represented by an array), inside an array. We can do this because JavaScript arrays are simply pointers to data (or the raw data itself if it's a simple variable like a number). You can call this sub approach an array of arrays.

An array that contains an array is treated in much the same manner as a multi-dimensional array, but is easier to conceptualize. So, for the above, if our structure were the first item in the array, I can find the phone number with the command

thePhone = myFriends[0][2];

This might be simpler to understand if we write it out long hand:

myStructure = myFriends[0];
thePhone = myStructure[2];

These two lines do the exact same thing, but with more typing.

So, we've just covered two topics in one. First, using an array as a structure. Second, using an array of arrays. If you choose to use array as a structure approach, you probably should set up some constant variables to help remember the correct indexes though. Your could might then look like this:

var INDEX_PHONE = 2;
. . .
thePhone = myFriends[0][INDEX_PHONE];

Isn't that easier to understand? Hmmm, but can we just use a string? somethine like this?

var bob = new Array();
bob["name"] = bob;
bob["phone"] = "555-1111";

That's even easier to read isn't it? And doesn't need us to define constant variables to help remember our indexing. In case you are wondering, YES, this works just fine. This method is known as an "associative" array.

Associative arrays are a more advanced use of arrays, and can sometimes be harder to understand in concept. In practice though, they are very easy. The real power of the associative arrays though is that the index can now be a meaningful string, and can be created by code if needed. Take this contrived example:

var firstname = "Bob";
var lastname = "Smith";
var myFriends = new Array();
myFriends[firstname + " " + lastname]["phone"] = "555-1111";

This translates of course to 'myFriends["Bob Smith"]["phone"]'. So, we no longer really even name a name field in our stored data - the name is the index. Of course, you have to be careful - do you know two people named Bob Smith??

Oh, did you know there's different ways to manually declare an array? We've been using the most academic method above. But, there's more options. Here's quick sample of the options:

var a1 = new Array();
var a2 = new Array(3);
var a3 = new Array(1,2,3,4,5);
var a4 = [ 1,2,3,4,5 ];

a1 - simply creates an empty array.
a2 - creates an array with 3 elements, but they are undefined. There is no real practical use to this method in JavaScript, because arrays will automatically grow as needed.
a3 - creates an array with 5 elements, containing the numbers 1 to 5.
a4 - is functionally identical to a3.

The a4 method is not mentioned too often in JavaScript textbooks, or tutorials, but you see custom libraries and objects using it quite often. I'm a bit of a traditionalist, and prefer the a1 method to creating my arrays. UNLESS I have to pass an array of data as a parameter to a function. Then I might do something like this:

result = myfunction([x,y,z]);

Well, even that feels contrived. I wouldn't write my functions in this way. But I have recently discovered a how good a fit the a4 method is when dealing with custom objects..

As you can see, there's more to JavaScript arrays than first appearances. When you are dealing with complex data, you can use arrays quite effectively to represent your information. Languages like PHP do this quite extensively. The method you use to represent your data though is up to you. What makes the most sense for your application? What do you best understand? What is the best match for the type of processing you'll be doing on the data? These are all decisions that you as the programmer/designer get to make.

I personally prefer to use a different method for representing complex data though - custom objects. We'll talk about that in our next session though...