Previous section   Next section

9.2 Multidimensional Arrays

Arrays can be thought of as long rows of slots into which values can be placed. Once you have a picture of a row of slots, imagine ten rows, one on top of another. This is the classic two-dimensional array of rows and columns. The rows run across the array and the columns run up and down the array, as illustrated in Figure 9-1.

Figure 9-1. Rows and columns create a multidimensional array
figs/pvn2_0901.gif

A third dimension is possible but somewhat harder to picture. Imagine making your arrays three-dimensional, with new rows stacked atop the old two-dimensional array. OK, now imagine four dimensions. Now imagine ten.

Those of you who are not string-theory physicists have probably given up, as have I. Multidimensional arrays are useful, however, even if you can't quite picture what they would look like. You might, for example, use a four-dimensional array to track movement in three dimensions (x,y,z) over time.

VB.NET supports two types of multidimensional arrays: rectangular and jagged. In a rectangular array, every row is the same length. In a jagged array, however, each row can be a different length. In fact, you can think of each row in a jagged array as an array unto itself. Thus, a jagged array is actually an array of arrays.

9.2.1 Rectangular Arrays

A rectangular array is an array of two (or more) dimensions. In the classic two-dimensional array, the first dimension is the number of rows and the second dimension is the number of columns.

To declare and instantiate a two-dimensional rectangular array named rectangularArray that contains two rows and three columns of integers, you could use either of the following syntax lines:

Dim rectangularArray (,) As Integer
Dim rectangularArray As Integer(,)

Either line will create an empty two-dimensional array.

In Example 9-6, you create a two-dimensional array of integers, and you populate the array using two For loops. The outer For loop iterates once for each row, and the inner For loop iterates once for each column in each row:

Dim i As Integer
For i = 0 To rows - 1
    Dim j As Integer
    For j = 0 To columns - 1
        rectangularArray(i, j) = i + j
    Next j
Next i

You then use a second set of For loops to display the contents of the array:

For i = 0 To rows - 1
    Dim j As Integer
    For j = 0 To columns - 1
        Console.WriteLine( _
          "rectangularArray[{0},{1}] = {2}", _
          i, j, rectangularArray(i, j))
    Next j
Next i

Note that for the second loop you do not redeclare the variable i, because it was declared earlier. You do, however, redeclare j, because the first instance of j was declared within the scope of the earlier For loop, and so is not visible here.

The complete listing is shown in Example 9-6, followed by the output.

Example 9-6. Rectangular array
Option Strict On
Imports System

Namespace ArrayDemo

    Class Tester

        Public Sub Run( )
            Const rowsUB As Integer = 4
            Const columnsUB As Integer = 3

            'declare a 4x3 Integer array
            Dim rectangularArray(rowsUB, columnsUB) As Integer

            'populate the array
            Dim i As Integer
            For i = 0 To rowsUB - 1
                Dim j As Integer
                For j = 0 To columnsUB - 1
                    rectangularArray(i, j) = i + j
                Next j
            Next i

            'report the contents of the array
            For i = 0 To rowsUB - 1
                Dim j As Integer
                For j = 0 To columnsUB - 1
                    Console.WriteLine( _
                      "rectangularArray[{0},{1}] = {2}", _
                      i, j, rectangularArray(i, j))
                Next j
            Next i
        End Sub 'Run

        Shared Sub Main( )
            Dim t As New Tester( )
            t.Run( )
        End Sub 'Main
    End Class 'Tester

End Namespace 'ArrayDemo

Output:
rectangularArray[0,0] = 0
rectangularArray[0,1] = 1
rectangularArray[0,2] = 2
rectangularArray[1,0] = 1
rectangularArray[1,1] = 2
rectangularArray[1,2] = 3
rectangularArray[2,0] = 2
rectangularArray[2,1] = 3
rectangularArray[2,2] = 4
rectangularArray[3,0] = 3
rectangularArray[3,1] = 4
rectangularArray[3,2] = 5

In Example 9-6, you declare a pair of constant values to be used to specify the upper bound of the rows (rowsUB) and the upper bound of the columns (columnsUB) in the two-dimensional array:

Const rowsUB As Integer = 4
Const columnsUB As Integer = 3

Creating these constants allows you to refer to these values throughout the program; if you decide later to change the value of either, you only have to make the change in one location in your code.

You use these upper bounds to declare the array:

Dim rectangularArray(rowsUB, columnsUB) As Integer

Notice the syntax. The parentheses indicate that the type is an array, and the comma indicates the array has two dimensions; two commas would indicate three dimensions, and so on.

Just as you can initialize a one-dimensional array using bracketed lists of values, you can initialize a two-dimensional array using similar syntax:

Dim rectangularArray As Integer(,) = _
   {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}

The outer braces mark the entire array initialization; the inner braces mark each of the elements in the second dimension. Since this is a 4 x 3 array (four rows by three columns), you have four sets of three initialized values (12 in all). Example 9-7 rewrites the Run( ) method from Example 9-6 to use initialization.

Example 9-7. Initializing a two-dimensional array
Public Sub Run( )
    Const rowsUB As Integer = 4
    Const columnsUB As Integer = 3

    'define and initialize the array
    Dim rectangularArray As Integer(,) = _
       {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}

    'report the contents of the array
    Dim i As Integer
    For i = 0 To rowsUB - 1
           Dim j As Integer
           For j = 0 To columnsUB - 1
                  Console.WriteLine( _
                     "rectangularArray[{0},{1}] = {2}", _
                     i, j, rectangularArray(i, j))
           Next j
    Next i
End Sub 'Run

Output:
rectangularArray[0,0] = 0
rectangularArray[0,1] = 1
rectangularArray[0,2] = 2
rectangularArray[1,0] = 3
rectangularArray[1,1] = 4
rectangularArray[1,2] = 5
rectangularArray[2,0] = 6
rectangularArray[2,1] = 7
rectangularArray[2,2] = 8
rectangularArray[3,0] = 9
rectangularArray[3,1] = 10
rectangularArray[3,2] = 11

As the output illustrates, the VB.NET compiler understands the syntax of your initialization; the objects are accessed with the appropriate offsets.

You might guess that this is a 12-element array, and that you can just as easily access an element at rectangularArray(0,3) as at rectangularArray(1,0), but if you try you will run right into an exception:

Unhandled Exception: System.IndexOutOfRangeException: 
Index was outside the bounds of the array.
   at DebuggingVB.ArrayDemo.Tester.Run( ) in ...Module1.vb:line 13
   at DebuggingVB.ArrayDemo.Tester.Main( ) in ...Module1.vb:line 29

The specification rectangularArray(0,3) addresses the array element at row 1 in column 4 (offset 0,3). Since the array has been defined as having four rows and three columns, this position does not exist in the array. VB.NET arrays are smart and they keep track of their bounds. When you define a 4 x 3 array, you must treat it as such, and not as a 3 x 4 or a 12 x 1 array.

Had you written the initialization as:

Dim rectangularArray As Integer(,) = _
{ {0,1,2,3}, {4,5,6,7}, {8,9,10,11} }

you would instead have implied a 3 x 4 array, and rectangularArray(0,3) would be valid.

9.2.2 Jagged Arrays

A jagged array is an array of arrays. Specifically, a jagged array is a type of multidimensional array in which each row can be a different size from all the other rows. Thus, a graphical representation of the array has a "jagged" appearance, as in Figure 9-2.

Figure 9-2. Jagged array
figs/pvn2_0902.gif

You can think of each row in a jagged array as an array unto itself�a one-dimensional array. Thus, technically speaking, a jagged array is an array of arrays. When you create a jagged array, you declare the number of rows in your array. Each row will hold a one-dimensional array, and each row can be of any length. To declare a jagged array you use the following syntax, where the number of pairs of parentheses indicates the number of dimensions of the array:

Dim identifier( )( ) As type

For example, you would declare a two-dimensional jagged array of integers named myJaggedArray as follows:

Dim myJaggedArray( )( ) As Integer

You address the elements in the array as follows: The array name followed by the offset into the array of arrays (the row), followed by the offset into the chosen array (the column within the chosen row). That is, to access the fifth element of the third array, you would write:

myJaggedArray(2)(4)

Remember that all arrays are zero-based. The third element is at offset 2, and the fifth element is at offset 4.

Example 9-8 creates a jagged array named myJaggedArray, initializes its elements, and then prints their content. To save space, the program takes advantage of the fact that integer array elements are automatically initialized to zero, and it initializes the values of only some of the elements.

Example 9-8. Jagged array
Option Strict On
Imports System

Namespace JaggedArray
    Public Class Tester
        Public Sub Run( )
            Const rowsUB As Integer = 3  'upper bounds
            Const rowZero As Integer = 5
            Const rowOne As Integer = 2
            Const rowTwo As Integer = 3
            Const rowThree As Integer = 5

            Dim i As Integer

            'declare the jagged array as 4 rows high
            Dim jaggedArray(rowsUB)( ) As Integer

            'declare the rows of various lengths
            ReDim jaggedArray(0)(rowZero)
            ReDim jaggedArray(1)(rowOne)
            ReDim jaggedArray(2)(rowTwo)
            ReDim jaggedArray(3)(rowThree)

            'fill some (but not all) elements of the rows           
            jaggedArray(0)(3) = 15
            jaggedArray(1)(1) = 12
            jaggedArray(2)(1) = 9
            jaggedArray(2)(2) = 99
            jaggedArray(3)(0) = 10
            jaggedArray(3)(1) = 11
            jaggedArray(3)(2) = 12
            jaggedArray(3)(3) = 13
            jaggedArray(3)(4) = 14

            For i = 0 To rowZero
                Console.WriteLine("jaggedArray(0)({0}) = {1}", _
                    i, jaggedArray(0)(i))
            Next

            For i = 0 To rowOne
                Console.WriteLine("jaggedArray(1)({0}) = {1}", _
                    i, jaggedArray(1)(i))
            Next

            For i = 0 To rowTwo
                Console.WriteLine("jaggedArray(2)({0}) = {1}", _
                    i, jaggedArray(2)(i))
            Next

            For i = 0 To rowThree
                Console.WriteLine("jaggedArray(3)({0}) = {1}", _
                    i, jaggedArray(3)(i))
            Next
        End Sub

        Public Shared Sub Main( )
            Dim t As Tester = New Tester( )
            t.Run( )
        End Sub
    End Class

End Namespace

Output:
jaggedArray(0)(0) = 0
jaggedArray(0)(1) = 0
jaggedArray(0)(2) = 0
jaggedArray(0)(3) = 15
jaggedArray(0)(4) = 0
jaggedArray(0)(5) = 0
jaggedArray(1)(0) = 0
jaggedArray(1)(1) = 12
jaggedArray(1)(2) = 0
jaggedArray(2)(0) = 0
jaggedArray(2)(1) = 9
jaggedArray(2)(2) = 99
jaggedArray(2)(3) = 0
jaggedArray(3)(0) = 10
jaggedArray(3)(1) = 11
jaggedArray(3)(2) = 12
jaggedArray(3)(3) = 13
jaggedArray(3)(4) = 14
jaggedArray(3)(5) = 0

Example 9-8 creates a jagged array with four rows:

Dim jaggedArray(rowsUB)( ) As Integer

Notice that the size of the second dimension is not specified. The columns in a jagged array vary by row; thus they are set by creating a new array for each row. Each of these arrays can have a different size:

ReDim jaggedArray(0)(rowZero)
ReDim jaggedArray(1)(rowOne)
ReDim jaggedArray(2)(rowTwo)
ReDim jaggedArray(3)(rowThree)  

If you look back at the values of the constants (rowZero through rowThree), you'll be able to figure out that there are 15 slots in this array.

Notice that you use the keyword ReDim (discussed earlier) to dimension the internal arrays. Here it is being used to resize the internal arrays from their initial size of zero to the size you designate.

Once an array size is specified for each row, you need only populate the various members of each array (row) and then print out their contents to ensure that all went as expected.

Notice that when you accessed the members of the rectangular array, you put the indexes all within one set of parentheses:

rectangularArray(i,j)

while with a jagged array you need two sets of parentheses:

jaggedArray(3)(i)

You can keep this straight by thinking of the first as a single array of more than one dimension and the jagged array as an array of arrays.


  Previous section   Next section
Top