Multidimensional Arrays






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 10 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 shown in Figure.

Rows and columns create a multidimensional array


A third dimension is a bit harder to imagine. Okay, now imagine four dimensions. Now imagine 10.

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.

C# supports two types of multidimensional arrays: rectangular and jagged. In a rectangular array, every row is the same length. A jagged array, however, is an array of arrays, each of which can be a different length.

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 a two-dimensional array, use the following syntax:

    type [,] array-name

For example, to declare and instantiate a two-dimensional rectangular array named myRectangularArray that contains two rows and three columns of integers, you would write:

    int [,] myRectangularArray = new int[2,3];

Figure declares, instantiates, initializes, and prints the contents of a two-dimensional array. In this example, a for loop is used to initialize the elements of the array.

Rectangular arrays

using System;

namespace RectangularArray
{
   public class Tester
   {
      static void Main( )
      {
         const int rows = 4;
         const int columns = 3;

         // declare a 4x3 integer array
         int[,] rectangularArray = new int[rows, columns];

         // populate the array
         for ( int i = 0; i < rows; i++ )
         {
            for ( int j = 0; j < columns; j++ )
            {
               rectangularArray[i, j] = i + j;
            }
         }

         // report the contents of the array
         for ( int i = 0; i < rows; i++ )
         {
            for ( int j = 0; j < columns; j++ )
            {
               Console.WriteLine( "rectangularArray[{0},{1}] = {2}",
                  i, j, rectangularArray[i, j] );
            }
         }
      }
   }
}

The output looks like this:

    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

The brackets in the int[,] declaration indicate that the type is an array of integers, and the comma indicates the array has two dimensions (two commas would indicate three dimensions, and so on). The actual instantiation of rectangularArray with new int[rows, columns] sets the size of each dimension. Here, the declaration and instantiation have been combined.

The program fills the rectangle with a pair of nested for loops, iterating through each column in each row. Thus, the first element filled is rectangularArray[0,0], followed by rectangularArray[0,1] and rectangularArray[0,2]. Once this is done, the program moves on to the next rows: rectangularArray[1,0], rectangularArray[1,1], rectangularArray[1,2], and so forth, until all the columns in all the rows are filled.

Just as you can initialize a one-dimensional array using bracketed lists of values, you can initialize a two-dimensional array using similar syntax. Figure declares a two-dimensional array (rectangularArray), initializes its elements using bracketed lists of values, and then prints out the contents.

Initializing a multidimensional array

using System;

namespace InitializingMultiDimensionalArray
{
   public class Tester
   {
      static void Main( )
      {
         const int rows = 4;
         const int columns = 3;

         // imply a 4x3 array
         int[,] rectangularArray =
         {
             {0,1,2}, {3,4,5}, {6,7,8}, {9,10,11}
         };

         for ( int i = 0; i < rows; i++ )
         {
            for ( int j = 0; j < columns; j++ )
            {
               Console.WriteLine( "rectangularArray[{0},{1}] = {2}",
                  i, j, rectangularArray[i, j] );
            }
         }
      }
   }
}

The output looks like this:

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

The preceding example is very similar to Figure, but this time you imply the exact dimensions of the array by how you initialize it:

    int[,] rectangularArrayrectangularArray =
    {
        {0,1,2}, {3,4,5}, {6,7,8}, {9,10,11}
    };

Assigning values in four bracketed lists, each consisting of three elements, implies a 4 (rows) by 3 (columns) array.

Had you written this as:

    int[,] rectangularArrayrectangularArray =
    {
       {0,1,2,3}, {4,5,6,7}, {8,9,10,11}
    };

you would instead have implied a 3 by 4 array.

You can see that the C# compiler understands the implications of the way you grouped the input values, because it is able to access the objects with the appropriate offsets, as illustrated in the output.

C# arrays are "smart" and they keep track of their bounds. When you imply a 4 x 3 array, you must treat it as such, and not as a 3 x 4 array, or just an array of 12 integers (as you can with some other C-family languages).

Jagged Arrays

A jagged array is an array of arrays. It is called "jagged" because each of the rows need not be the same size as all the others, and thus a graphical representation of the array would not be square.

When you create a jagged array, you declare the number of rows in your array. Each row will hold an array, which can be of any length. These arrays must each be declared. You can then fill in the values for the elements in these "inner" arrays.

In a jagged array, each dimension is a one-dimensional array. To declare a jagged array, use the following syntax, where the number of brackets indicates the number of dimensions of the array:

    type [] []...

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

    int [] [] myJaggedArray;

Access the fifth element of the third array by writing myJaggedArray[2][4].

Remember that in all arrays, the first element is at offset 0 and the nth element is at offset n - 1; thus, the seventh element is at offset 6.


Figure 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.

Working with a jagged array

using System;
namespace JaggedArray
{
   public class Tester
   {
      static void Main( )
      {
         const int rows = 4;

         // declare the jagged array as 4 rows high
         int[][] jaggedArray = new int[rows][];

         // the first row has 5 elements
         jaggedArray[0] = new int[5];

         // a row with 2 elements
         jaggedArray[1] = new int[2];

         // a row with 3 elements
         jaggedArray[2] = new int[3];

         // the last row has 5 elements
         jaggedArray[3] = new int[5];

         // 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 ( int i = 0; i < 5; i++ )
         {
            Console.WriteLine( "jaggedArray[0][{0}] = {1}",
               i, jaggedArray[0][i] );
         }

         for ( int i = 0; i < 2; i++ )
         {
            Console.WriteLine( "jaggedArray[1][{0}] = {1}",
               i, jaggedArray[1][i] );
         }

         for ( int i = 0; i < 3; i++ )
         {
            Console.WriteLine( "jaggedArray[2][{0}] = {1}",
               i, jaggedArray[2][i] );
         }
         for ( int i = 0; i < 5; i++ )
         {
            Console.WriteLine( "jaggedArray[3][{0}] = {1}",
               i, jaggedArray[3][i] );
         }
      }
   }
}

The output looks like this:

    jaggedArray[0][0] = 0
    jaggedArray[0][1] = 0
    jaggedArray[0][2] = 0
    jaggedArray[0][3] = 15
    jaggedArray[0][4] = 0
    jaggedArray[1][0] = 0
    jaggedArray[1][1] = 12
    jaggedArray[2][0] = 0
    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

In this example, a jagged array is created with four rows:

    int[][] jaggedArray = new int[rows][];

Notice that the second dimension is not specified. This is set by creating a new array for each row. Each of these arrays can have a different size:

    // the first row has 5 elements
    jaggedArray[0] = new int[5];

    // a row with 2 elements
    jaggedArray[1] = new int[2];

    // a row with 3 elements
    jaggedArray[2] = new int[3];

    // the last row has 5 elements
    jaggedArray[3] = new int[5];

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

Another way of outputting the values would be to use two nested for loops, and use the Length property of the array to control the loop:

    for (int i = 0; i < jaggedArray.Length; i++ )
    {
       for (int j = 0; j < jaggedArray[i].Length; j++)
       {
          Console.WriteLine("jaggedArray[{0}][{1}] = {2}",
          i, j, jaggedArray[i][j]);
       }
    }

In this case, the "outer" for loop iterates over the rows in the array. The "inner" loop outputs each column in the given row. Because you're using Length to control how many times the loop runs, it doesn't matter that each row is a different length.

Notice that when you access the members of the rectangular array, you put the indexes all within one set of square brackets:

    rectangularArrayrectangularArray[i,j]

while with a jagged array, you need a pair of brackets:

    jaggedArray[i][j]

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 .



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows