C# Intermediate

C# Jagged Array (Array of Arrays)

Table of Contents

There are two variants of two-dimensional arrays: Rectangular array and Jagged array.

The Array of Arrays

C# jagged array is an array of arrays, which means it’s an array that contains other arrays (inner arrays for clarity). Of course, such inner arrays can have different lengths, or they can even be not initialized.

Think of a table with the rows of unequal lengths. When you create a jagged array, you declare the number of fixed rows in the array. Then, each row can have a different number of columns. To be more specific, jagged is a single-dimensional array, where each row will hold another array of different dimensions 😊.

If you look at the following example, you will see a jagged array with three rows/elements. Row 0 has two columns, row 1 has four columns, while the last row 2 has three columns:

C# Jagged Array

Note: The elements of the jagged array can be one-dimensional and multi-dimensional arrays.

By the end of this article, you’ll know:

  • What jagged is and how to write a jagged array.
  • Why the jagged array is an array of arrays.
  • How to declare a jagged array.
  • How to initialize a jagged array with values.
  • How to access values in a jagged array.
  • How to loop through jagged array elements and print the values.
  • Useful properties and methods of a jagged array.
  • Jagged array vs. 2d array.

When you’re finished, you should have a good understanding of how to use a jagged array in C#.

Edit, and test all the CODE examples used in this article with C# online editor:  Code Playground

In Short: C# Jagged Array

  • Also called an array of arrays.
  • Elements of a jagged array are fixed, and each element can hold a separate array of its own. The inner array can have a different length than those in the other rows.
  • Think of a table that has “rows” of varied sizes.
  • The declaration statement must specify the number of rows in the array. Then, declare the number of columns in each row before you assign values to the elements in that row.

Syntax to Declare and Initialize Jagged Array

To declare a jagged array, we use two sets of square brackets in the array’s declaration. The notation ([ ][ ]) is used after the data type to represent the number of dimensions. Here is an example of a jagged array declaration:

Syntax

type[][] arrayName;

Syntax to Declare Jagged Array (Array of Arrays)

To initialize the jagged array, only the size that determines the number of rows in the first pair of brackets is set. Also, notice that the second bracket that defines the number of elements inside the row is empty because every row has a different number of columns. The column sizes must be set individually.

Syntax

arrayName = new type[rows][];

Syntax to Initialize Jagged Array (Array of Arrays)

Another way is to declare and initialize an array at the same time on a single line.

Syntax

type[][] arrayName = new type[rows][];

Syntax to Declare and Initialize Jagged Array (Array of Arrays)

Create a Jagged Array

The below line creates fruits with two elements, each of type string[] and with an initial value of null.

string[][] fruits = new string[2][]; // correct
Declare Jagged Array of string with 2 Rows

string[2][]indicates a jagged array has 2 rows, and the number of columns is unclear.

When you use the new keyword to create the jagged array, you specify the number of rows that the array will contain.

The following statement is a syntax error:

string[][] fruits = new string[2][2]; // error

A jagged array cannot be created entirely with a single statement. Instead, you need to initialize the elements of a jagged array separately.


Assign Values to a Jagged Array

Once the array is declared, you now need to construct each row in the array and fill it with data. There are two ways to do this: you can allocate the elements—one per row or use an initialization list to assign data all at once.

Using the first method, you can write:

fruits[0] = new string[2];
fruits[1] = new string[3];

The above lines initialize the two elements of fruits with individual array instances of different dimensions—one statement at a time.

Declare And Initialize Jagged Array of string With 2 Rows
  • fruits[0] = new string[2]indicates row 0 has 2 columns.
  • fruits[1] = new string[3]indicates row 1 has 3 columns.

Let’s take a closer look at the index values for the above array.

Index Values of a Jagged Array of string With 2 Rows

You can access an indexed array element, which is part of the jagged array using two indexers ([rowIndex] [columnIndex]), and then assign a value to it with assignment operator (=). Look at the following statements.

fruits[0][0] = "Apple";
fruits[0][1] = "Apricot";

fruits[1][0] = "Mango";
fruits[1][1] = "Orange";
fruits[1][2] = "Melon";
Assign values to the Indexes of a Jagged Array of string With 2 Rows
  • fruits[0][0] = "Apple"indicates value Apple assigned to the 1st column[0]of the 1st row[0]
    fruits[0][1] = "Apricot"indicates value Apricot assigned to the 2nd column[1]of the 1st row[0]
  • fruits[1][0] = "Mango"indicates value Mango assigned to the 1st column[0]of the 2nd row[1]
    fruits[1][1] = "Orange"indicates value Orange assigned to the 2nd column[1]of the 2nd row[1]
    fruits[1][2] = "Melon"indicates value Melon assigned to the 3rd column[2]of the 2nd row[1]

Another way that allows initial values of the array elements to be assigned is with the new operator using an array initializer, a list of values written between the curly-bracket { and }.

fruits[0] = new string[] { "Apple", "Apricot" };
fruits[1] = new string[] { "Mango", "Orange", "Melon" };

The above code adds three separate one-dimensional arrays—one statement at a time.

  • The first element[0],which is an string array with two columns. The columns are initialized with the values Apple and Apricot.
  • The second element[1],which is an string array with three columns. The columns are initialized with the values Mango, Orange and Melon.

In the second method, you can use a modified form of the above and assign values all at once using an array initializer.

string[][] fruits = new string[2][] { new string[] { "Apple", "Apricot" }, new string[] { "Mango", "Orange", "Melon" } }; 

Note: The length of the array is inferred from the number of values between the delimiters {}.

Let’s take array initializer one stage further and omit the size that defines the rows. The C# compiler determines the size from the number of elements assigned to it.

string[][] fruits = new string[][] { new string[] { "Apple", "Apricot" }, new string[] { "Mango", "Orange", "Melon" } };  

You can also write the above code in a different way, as shown here:

string[][] fruits = { new string[] { "Apple", "Apricot" }, new string[] { "Mango", "Orange", "Melon" } }; 

Note: You cannot omit the new operator from the element’s initialization.

Another approach is to use the var keyword. This keyword instructs the compiler to implicitly type a local variable:

var fruits =  new[] { new string[] { "Apple", "Apricot" }, new string[] { "Mango", "Orange", "Melon" } }; 

Run Demo


Access Individual Elements of a Jagged Array

You refer to each element of the array using its row and column index with two indexers ([ ][ ]).

Syntax

arrayName[rowIndex][columnIndex]

Example

fruits[1][1];

Let me repeat this.

To access an item stored at a particular row and column in a jagged array, you enclose the row and column index in their own sets of brackets. For example, the above fruits[1][1] statement displays the value stored at row 1, column 1, of the fruits, as shown here:

Access Individual Elements of a Jagged Array

Access whole row of data using the following syntax.

Syntax

arrayName[row]

Example

fruits[1]
Access Whole Row Data of Jagged Array

Let’s display values using foreach loop.

string display = string.Empty;  

foreach (string rowValue in fruits[1]) 
{        
    display +=   rowValue + " ";

    // line break
    display += "\n"; 
}  
Console.WriteLine(display);

Run Demo

OUTPUT

Mango
Orange
Melon


Example 1: Jagged Array with 3 Rows, Each Contains 1D Array of Integer Values

This array consists of three rows.

int[][] intArray = new int[3][];

To assign values to a jagged array element, you can have arrays of different lengths for each element. In the following example, a jagged array is composed of three separate single-dimensional arrays—one per row.

intArray[0] = new int[] { 1, 2 };
intArray[1] = new int[] { 3, 4, 5 };
intArray[2] = new int[] { 6, 7, 8, 9 };

Alternatively, this is how you declare and initialize a jagged array with array initializer syntax, whose elements are arrays of integer values.

int[][] intArray = { new[] { 1, 2 }, new[] { 3, 4, 5 }, new[] { 6, 7, 8, 9 } };
jagged array with 3 rows of different sizes
  • int[3][]indicates jagged array has 3 rows and the number of columns is undefined.
  • intArray[0] = new int[]indicates row 0 has 2 columns with the values{1, 2}.
  • intArray[1] = new int[]indicates row 1 has 3 columns with the values{3, 4, 5}.
  • intArray[2] = new int[]indicates row 2 has 4 columns with the values{6, 7, 8, 9}.

Index values for the above array.

Jagged Array Index Values

You can access each element of the arrays, which are part of the jagged array, using their index. The index positions are used inside two indexers ([ ] [ ]) when retrieving the value from an array.

intArray[0][0]; // return 1

The above statement fetches a value 1 from the 1st column ([0]) of the 1st row ([0]), which displays the value of the element [0, 0] of the 1st array.

intArray[1][2]; // return 5

The above statement fetches a value 5 from the 3rd column ([2]) of the 2nd row ([1]), which displays the value of the element [1, 2] of the 2nd array.

intArray[2][1]; // return 7

The above statement fetches a value 7 from the 2nd column ([1]) of the 3rd row ([2]), which displays the value of the element [2, 1] of the 3rd array.

Jagged Array Get Values By index

You can access a value of an indexed array element, which is part of the jagged array, by using two indexers ([ ] [ ]) and then assign a value to it with assignment operator (=). Look at the following statements.

intArray[0][0] = 10;

The above statement assigns a value 10 to the 1st column ([0]) of the 1st row ([0]), which updates the value of the element [0, 0] of the 1st array from 1 to 10.

intArray[1][2] = 50;

The above statement assigns a value 50 to the 3rd column ([2]) of the 2nd row ([1]), which updates the value of the element [1, 2] of the 2nd array from 5 to 50.

intArray[2][1] = 70;

The above statement assigns a value 70 to the 2nd column ([1]) of the 3rd row ([2]), which updates the value of the element [2, 1] of the 3rd array from 7 to 70.

Jagged Array Set Values By index

Run Demo


Example 2: Jagged Array with 2 Rows, Each Contains 1D Array of Char Values

This array consists of two rows.

char[][] charArray = new char[2][];

Let’s assign values to the elements of a jagged array. In the following example, a jagged array is composed of two separate single dimensional arrays of char values — one per row.

charArray[0] = new char[] { 'A', 'B', 'C' };
charArray[1] = new char[] { 'D', 'E' };

Another way is to declare and initialize a jagged array with array initializer syntax.

char[][] charArray = { new[] { 'A', 'B', 'C' }, new[] { 'D', 'E' } };
Jagged Array with 2 rows of different sizes
  • char[2][]indicates jagged array has 2 rows and the number of columns is undefined.
  • charArray[0] = new char[]indicates row 0 has 3 columns with the values{ 'A', 'B', 'C' }.
  • charArray[1] = new char[]indicates row 1 has 2 columns with the values{ 'D', 'E' }.

Index values for the above array.

Jagged Array With 2 Rows Index Values

The index positions are used inside two indexers ([ ] [ ]) when retrieving the value from an array.

charArray[0][2]; // return C

The above statement fetches a value C from the 3rd column ([2]) of the 1st row ([0]), which displays the value of the element [0, 2] of the 1st array.

charArray[1][1]; // return E

The above statement fetches a value E from the 2nd column ([1]) of the 2nd row ([1]), which displays the value of the element [1, 1] of the 2nd array.

Jagged Array With 2 Rows Get Index Values

You can access the value of an indexed array element by using two indexers ([ ] [ ]) and then assign a value to it with an assignment operator (=).

charArray[0][2] = 'F';

The above statement assigns a value ‘F’ to the 3rd column ([2]) of the 1st row ([0]), which updates the value of the element [0, 2] of the 1st array from ‘C’ to ‘F’.

charArray[1][1] = 'G';

The above statement assigns a value ‘G’ to the 2nd column ([1]) of the 2nd row ([1]), which updates the value of the element [1, 1] of the 2nd array from ‘E’ to ‘G’.

Jagged Array With 2 Rows Set Values By Index

Run Demo


Example 3: Jagged Array with 2 Rows, Each Contains 2D Array of Char values

In the following example, a single-dimensional jagged array consists of two rows, each of which contains two separate multi-dimensional array elements of different sizes—one per row.

char[][,] charArray = new char[2][,];

Let’s assign values to the elements of a jagged array.

charArray[0] = new char[,] { { 'A', 'B', 'C' }, { 'D', 'E', 'F' } };
charArray[1] = new char[,] { { 'G', 'H' }, { 'I', 'J' } };

Alternatively, you declare and initialize a jagged array with an array initializer whose elements are multi-dimensional arrays.

char[][,] charArray = new char[2][,] 
{
    new char[,] { { 'A', 'B', 'C' }, { 'D', 'E', 'F' } },
    new char[,] { { 'G', 'H' }, { 'I', 'J' } }
};
Jagged Array With 2 Rows 2 Rectangular Array

The index position is used inside a pair of indexers ([ ] [ ]) when retrieving the value from an individual array element. The first bracket is used for the jagged array row, and the second bracket indicates the element within that row.

charArray[0][0, 2]; // return C

Jagged array 1st row ([0]) indicated by the first bracket contains the element [0, 2]. Therefore, the above statement fetches value C from the 3rd column ([2]) of the 1st row ([0]), which displays the value of the element [0, 2] of the 1

charArray[1][1, 1]; // return J

Jagged array 2nd row ([1]) indicated by the first bracket contains the element [1, 1]. Therefore, the above statement fetches a value J from the 2nd column ([1]) of the 2nd row ([1]), which displays the value of the element [1, 1] of the 2nd array.

Jagged Array With 2 Rows 2 Rectangular Array Get Value

You can access the value of an indexed array element by using two indexers ([ ] [ ]) and then assign a value to it with an assignment operator (=).

charArray[0][0, 2] = 'K';

Jagged array 1st row ([0]) indicated by the first bracket contains the element [0, 2]. Therefore, the above statement assigns a value K to the 3rd column of the 1st row, which updates the element [0, 2] of the 1st array from C to K.

charArray[1][1, 1] = 'L';

Jagged array 2nd row ([0]) indicated by the first bracket contains the element [1, 1]. Therefore, the above statement assigns a value L to the 2nd column of the 2nd row, which updates the element [1, 1] of the 2nd array from J to L.

Jagged Array With 2 Rows 2 Rectangular Array Update Value

Run Demo


Example 4: Jagged Array of Strings

You can declare a jagged array of strings as

string[][] fruits = { new string[] { "Apple", "Banana" }, new string[] { "Orange", "Papaya", "Apricot", "Cherry" } };

Another way with var keyword

var fruits =  new[] { new string[] { "Apple", "Banana" }, new string[] { "Orange", "Papaya", "Apricot", "Cherry" } };

Length and Rank Properties of a Jagged Array

All arrays have a Length property that returns the total number of elements in an array. For a jagged array, the Length property returns the number of rows/elements. Again, each row has a Length property to retrieve the number of columns in that row.

Syntax

arrayName.Length

The following example displays the total number of rows in the intArray.

Example

Console.WriteLine( $"There are { intArray.Length } rows in the array.");

Note: Arrays have a fixed length, which cannot be changed without re-creating the array.

The Rank property, on the other hand, returns the number of dimensions of the current array. You can say it is one plus the number of commas in the array’s square-brackets ([ ]).

Syntax

arrayName.Rank

Example

int[] intArray1 = new int[3];
int[,] intArray2= new int[3,2];
int[,,] intArray3= new int[3,2,2];
int[][] jaggedArray = new int[3][];

Console.WriteLine($"[]: {intArray1.Rank} dimension");
Console.WriteLine($"[,]: {intArray2.Rank} dimensions");
Console.WriteLine($"[,,]: {intArray3.Rank} dimensions");
Console.WriteLine($"[][]: {jaggedArray.Rank} dimension");

OUTPUT

[]: 1 dimension
[,]: 2 dimensions
[,,]: 3 dimensions
[][]: 1 dimension

Note: A jagged array is a one-dimensional array; the value of its Rank property is always 1. A multidimensional array can have any rank.

To retrieve the size of a particular rank, you use the GetLength() method. This method requires the rank whose length will be returned.

Console.WriteLine($"[][]: {jaggedArray.GetLength(0)} elements");

OUTPUT

[][]: 3 elements

Displays 3 because that is the number of elements in the first dimension (rows).

Run Demo


GetLength Method of a Jagged Array

The GetLength() method gets the number of elements in the specified dimension of an array. Use this method if you want to extract the number of rows or columns in a two-dimensional array.

Syntax

arrayName.GetLength(dimensionIndex)

Where dimensionIndex = 0 for rows and dimensionIndex = 1 for columns.

The following example displays the elements in the first dimension of an intArray.

Example

intArray.GetLength(0)

Iterating Through Jagged Array Using Nested Loops

Never hardcode total number elements, when you want to iterate through the array. Always use properties or methods such as Length and GetLength to determine the total number of iterations needed. Let’s look at the following examples.

Example 1: Loop Through Jagged Array Elements Using for Loop

string display = string.Empty;

int[][] intArray = { 
  new int[] { 1, 2 }, 
  new int[] { 3, 4, 5 }, 
  new int[] { 6, 7, 8, 9 } 
};

// Use intArray.GetLength(0) or intArray.Length
for (int row = 0; row < intArray.GetLength(0); row++)
{
    for (int column = 0; column < intArray[row].Length; column++)
    {
          display += intArray[row][column].ToString() + " ";
    }

    display += "\n";
}

Console.WriteLine(display);

The following output displays the rows and every element within that row.

Run Demo

OUTPUT

1 2
3 4 5
6 7 8 9

First, declared and initialized jagged intArray variable. On the left side of the declaration, a pair of two square brackets ([ ][ ]) indicate the number of dimensions. The array is two-dimensional; that’s why you need to use two separate for loops to iterate through each row and every element within that row.

Outer for loop is to get the number of rows by calling the GetLength method and passing 0 for the dimension; instead, you can use the Length property as well. On the other hand, nested for loop requires a different approach because each row of a jagged array contains a different number of columns. Therefore, instead of the GetLength method to return the number of columns for that row, you use the Length property of the array.

Finally, within the inner loop, you use variable intArray with the loop counter “row” for rowIndex and “column” for columnIndex inside two sets of square brackets ([ ] [ ]) to refer to each element in the array.

So the outer loop iterates through every row, and the inner loop iterates through every element inside that row.

Example 2: Loop Through Jagged Array Elements Using foreach Loop

C# provides another loop, named foreach, which you can use to iterate all elements in all rows of the jagged array. You can not use the foreach loop directly because a jagged array is an array of arrays, which means a nested foreach loop must access each row and columns within that row.

The outer loop iterates through the rows, and the inner loop iterates through the columns of the selected row.

Suppose you have the following jagged array that contains three elements, each of which includes an array of integers values:

// Array Declaration
int[][] intArray = new int[3][];

// Array initialization 
intArray[0] = new int[] { 1, 2 }; 
intArray[1] = new int[] { 3, 4, 5 }; 
intArray[2] = new int[] { 6, 7, 8, 9 }; 

// Nested foreach loop
string display = string.Empty;  

foreach (int[] row in intArray) 
{        
       foreach (int column in row)         
       {                  
               display +=  column + " ";        
       }

      // move to the next line
      display += "\n"; 
}  

Console.WriteLine(display);

Run Demo

OUTPUT

1 2
3 4 5
6 7 8 9

The outer foreach loop iterates through each of the three rows in the intArray. The inner foreach loop outputs each element within that row.

Notice that there is no index used in the foreach loop. Lack of index reduces error and makes the loop simpler to read and write than the for loop. Sometimes the index is handy; then, you need to choose a for loop.

Example 3: Loop Through Jagged Array Composed of One-Dimensional Arrays of Char Values

string display = string.Empty;
char[][] charArray = { new[] { 'A', 'B', 'C' }, new[] { 'D', 'E' } };

for (int i = 0; i < charArray.GetLength(0); i++)
{
  for (int j = 0; j < charArray[i].Length; j++)
  {
		display += charArray[i][j].ToString() + " ";
  }

  display += "\n";
}

Console.WriteLine(display);

Run Demo

OUTPUT

A B C
D E

Example 4: Loop Through Jagged Array Composed of Two-Dimensional Arrays of Char Values

The elements of the jagged array can be single-dimensional and multidimensional arrays. In the following example, a single-dimensional jagged array consists of two rows, each of which contains two separate multi-dimensional array elements of different sizes—one per row.

string display = string.Empty;

char[][, ] charArray = new char[2][, ]{new char[, ]{{'A', 'B', 'C'}, {'D', 'E', 'F'}}, new char[, ]{{'G', 'H'}, {'I', 'J'}}, };

// First for loop is used to iterate through jagged array rows
for (int i = 0; i < charArray.Length; i++)
{
	display += $"Element({i}): \n";

	// For each jagged array row, 2nd and 3rd for loop is used iterate through elements on that row
	for (int j = 0; j < charArray[i].GetLength(0); j++)
	{
		// Column iteration
		for (int k = 0; k < charArray[i].GetLength(1); k++)
		{
			display += charArray[i][j, k].ToString() + " ";
		}

		display += "\n";
	}
}

Console.WriteLine(display);

Loop counters

  • i is used for jagged array row.
  • j (row) and k (column) is used for array element.

Run Demo

OUTPUT

Element(0):
A B C
D E F
Element(1):
G H
I J


The null Row Problem in a Jagged Array

C# compiler won’t check or complain if one or more rows in a jagged array remain uninitialized before being used for the first time. Let’s look at the following example.

Example

int[][] intArray = new int[4][]; // 4 rows

intArray[0] = new int[] { 1, 2 };
intArray[1] = new int[] { 3, 4, 5 };
intArray[2] = new int[] { 6, 7, 8, 9 };  
// Row 3 initialized with null value

Row 3 is uninitialized because we haven’t provided any value to it; thus, it remains null. The problem occurs when you try to access the row before assigning any value to it.

string display = string.Empty;  

foreach (int[] rowValue in intArray) 
{        
      foreach (int colValue in rowValue)         
      {                  
              display +=   colValue + " ";        
      }

     // move to the next line
     display += "\n"; 
}  
Console.WriteLine(display);

Run Demo

The outer foreach loop will still include row 3 as the value of rowValue, but when the inner foreach loop attempted to access the elements of row 3, a runtime NullReferenceException will occur with the message Object reference not set to an instance of an object.. The error is due to an attempt to read from a null reference.


Jagged Array vs Multidimensional Array

Both jagged and rectangular arrays are a form of multidimensional arrays, but the simplest one is a two-dimensional array.

A jagged array is like a two-dimensional array, but the “rows” in a jagged array can have a different number of columns. If you use ([ ][ ]), you are creating an array of arrays, where each array within a larger array has a different length.

Note: Inner arrays within the main array need not be equal size.

A traditional two-dimensional array has a rectangular size (for example, 3 × 3 elements), where each “row” has the same number of columns. For this reason, a 2D array is often called a square array or a rectangular array where each array within a larger array has the same length.

Note: Inner arrays within the main array are equal size.

Jagged Array vs Multidimensional Array

The jagged array shown contains three rows, the first row containing two elements, the second row with four elements, and the third row with three elements.

The following code shows an example of how the jagged array is created and initialized.

// Create an array of 3 int arrays.
 int[][] intArray = new int[3][]; 

// Create each array that is an element of the jagged  
intArray[0] = new int[] { 1, 2 };
intArray[1] = new int[] { 3, 4, 5, 6 };
intArray[2] = new int[] { 7, 8, 9 }; 

Let’s look at the following image.

Jagged Array Example

Rectangular arrays are created using commas to separate each dimension. The following code declares a two-dimensional array, where the dimensions are 3 × 2:

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

Assign values to the elements of the intArray using one statement at a time, as shown below.

intArray[0, 0] = 1;
intArray[0, 1] = 2;
intArray[1, 0] = 3;
intArray[1, 1] = 4;
intArray[2, 0] = 5;
intArray[2, 1] = 6;
two-dimensional array example

You can use array initializer to assign values all at once with curly bracket {…} notation.

intArray = new int[3, 2] { 
     { 1, 2 }, 
     { 3, 4 }, 
     { 5, 6 } 
}; 

Run Demo


C# Reference | Microsoft Docs


Community Input

💬 What other C# Jagged Array topics should I cover here?

Please use twitter to share your suggestions. We will add your feedback here.

Share With Love ❤️


Send this to a friend