Home
Map
2D Array ExamplesCreate and use 2D arrays, along with jagged arrays. Iterate over elements with for-loops.
C#
This page was last reviewed on Nov 29, 2023.
2D array. A two-dimensional array is used to store elements that are indexed by two coordinates. In C# we separate the indexes with a comma. We can create 2D arrays of any element type.
Shows a 2d arrayShows a 2d arrayShows an arrayShows an arrayShows a 2d loop
We can initialize 2D arrays with a single statement—all the memory is part of a single region. Also remember that jagged arrays can represent a 2D space.
Array
2D example. Here we show a 2-dimensional string array. The program creates a 2x2 string array and then prints out all 4 elements with Console.WriteLine.
Console.WriteLine
Part 1 Here we initialize the 2D array with an initializer expression. Each element in this array is a string.
Part 2 We use the indexing syntax to access elements. We use 2 indexes for a 2D array. Each dimension is indexed starting at zero.
Tip It makes no difference whether we think of the first index as a row or column, or the other way around.
Shows a 2d array
using System; // Part 1: create 2D array of strings. string[,] array = new string[,] { { "cat", "dog" }, { "bird", "fish" }, }; // Part 2: access (and print) values. Console.WriteLine(array[0, 0]); Console.WriteLine(array[0, 1]); Console.WriteLine(array[1, 0]); Console.WriteLine(array[1, 1]);
cat dog bird fish
Rank. Every array has a rank: this is the number of dimensions in the array. A one-dimensional array has a rank of 1. We access the Rank property from the Array base class.
Here We design a method (Handle) that receives an array reference. It then tests the Rank of the parameter array.
And In Handle() we test both 1D and 2D arrays in the same method. This method uses GetValue to access the array elements.
Shows a 2d array
using System; class Program { static void Main() { // ... A one-dimensional array. int[] one = new int[2]; one[0] = 1; one[1] = 2; Handle(one); // ... A two-dimensional array. int[,] two = new int[2, 2]; two[0, 0] = 0; two[1, 0] = 1; two[0, 1] = 2; two[1, 1] = 3; Handle(two); } static void Handle(Array array) { Console.WriteLine("Rank: " + array.Rank); switch (array.Rank) { case 1: for (int i = 0; i < array.Length; i++) { Console.WriteLine(array.GetValue(i)); } break; case 2: for (int i = 0; i < array.GetLength(0); i++) { for (int x = 0; x < array.GetLength(1); x++) { Console.Write(array.GetValue(i, x)); } Console.WriteLine(); } break; } } }
Rank: 1 1 2 Rank: 2 02 13
Jagged array. A jagged array is a single-dimensional array of other arrays. Because each element is another array, it can be used like a 2D array.
Part 1 First we create a jagged array of int elements. The array has 3 rows—so it can have 3 subarrays once they are all assigned.
int, uint
Part 2 We assign the indexes to new int arrays. We only have an array of empty references—new arrays must be created for the rows.
Part 3 We examine each item in the jagged array. We call Length first on the array of references, and iterate through the rows.
Part 4 We iterate over the inner arrays (the columns) and print all the element values to the screen.
Shows an array
using System; // Part 1: declare local jagged array with 3 rows. int[][] jagged = new int[3][]; // Part 2: create a new array in the jagged array. jagged[0] = new int[2]; jagged[0][0] = 1; jagged[0][1] = 2; jagged[1] = new int[1]; jagged[2] = new int[3] { 3, 4, 5 }; // Part 3: iterate overall the elements. for (int i = 0; i < jagged.Length; i++) { // Part 4: iterate over the inner array. // ... Print all its elements. int[] innerArray = jagged[i]; for (int a = 0; a < innerArray.Length; a++) { Console.Write(innerArray[a] + " "); } Console.WriteLine(); }
1 2 0 3 4 5
3D array. Here we see the use of a three-dimensional array. You can declare and initialize the multidimensional array using the comma syntax.
Info You can loop over any 3D array using this example code. Adding levels to the for-loop allows it to handle greater dimensions.
Here We use a three-dimensional integer array reference type. We specify the dimension lengths on the array creation expression.
int Array
Also We access elements in a 2D or 3D array using the comma syntax in the array index. We read and write elements using this syntax.
Shows an array
using System; // Create a three-dimensional array. int[, ,] threeDimensional = new int[3, 5, 4]; threeDimensional[0, 0, 0] = 1; threeDimensional[0, 1, 0] = 2; threeDimensional[0, 2, 0] = 3; threeDimensional[0, 3, 0] = 4; threeDimensional[0, 4, 0] = 5; threeDimensional[1, 1, 1] = 2; threeDimensional[2, 2, 2] = 3; threeDimensional[2, 2, 3] = 4; // Loop over each dimension's length. for (int i = 0; i < threeDimensional.GetLength(2); i++) { for (int y = 0; y < threeDimensional.GetLength(1); y++) { for (int x = 0; x < threeDimensional.GetLength(0); x++) { Console.Write(threeDimensional[x, y, i]); } Console.WriteLine(); } Console.WriteLine(); }
100 200 300 400 500 000 020 000 000 000 000 000 003 000 000 000 000 004 000 000
GetUpperBound loop. GetUpperBound() receives the highest index of the specified rank. It returns an int. The word rank is the same concept as "dimension."
Tip A 2D array has 2 ranks, 0 and 1. On more complex arrays, GetUpperBound will work more reliably than other approaches.
Shows a 2d loop
using System; string[,] codes = new string[,] { { "AA", "BB" }, { "CC", "DD" } }; // Get the upper bound. // ... Use for-loop over rows. for (int i = 0; i <= codes.GetUpperBound(0); i++) { string s1 = codes[i, 0]; string s2 = codes[i, 1]; Console.WriteLine("{0}, {1}", s1, s2); }
AA, BB CC, DD
Length-based loop. The fastest method for a 2D array is to do some arithmetic. In this example, there are five rows. GetUpperBound(0) will return 4.
And If we take Length, which is 10, and divide by 2, we get 5. We can iterate until we reach 5.
using System; string[,] words = new string[,] { { "ONE", "TWO" }, { "THREE", "FOUR" }, { "FIVE", "SIX" } }; // Loop based on length. // ... Assumes each subarray is two elements long. for (int i = 0; i < words.Length / 2; i++) { string s1 = words[i, 0]; string s2 = words[i, 1]; Console.WriteLine("{0}, {1}", s1, s2); }
ONE, TWO THREE, FOUR FIVE, SIX
GetUpperBound, int example. Here we get the 2 dimensions of the array and iterate through them. We cache array bounds in locals for better performance and clarity.
Info The performance of GetUpperBound can make an impact. But often, using jagged arrays (or flattened arrays) is the best solution.
Tip Var is used to reference the 2D array. This makes the syntax for the program simpler—var is often used with 2D arrays.
var
using System; var codes = new int[,] { { 200, 400 }, { 2000, 4000 }, { 20000, 40000 } }; // Get all bounds before looping. int bound0 = codes.GetUpperBound(0); int bound1 = codes.GetUpperBound(1); // ... Loop over bounds. for (int i = 0; i <= bound0; i++) { for (int x = 0; x <= bound1; x++) { // Display the element at these indexes. Console.WriteLine("ELEMENT: {0}", codes[i, x]); } Console.WriteLine("--"); }
ELEMENT: 200 ELEMENT: 400 -- ELEMENT: 2000 ELEMENT: 4000 -- ELEMENT: 20000 ELEMENT: 40000 --
No initializers. We can create an empty 2D array by specifying its dimensions. All elements have the default value (for ints this is 0).
Also We can use a 2D array reference to refer to any size of array, but the element type must match.
using System; // A two-dimensional array reference. int[,] array = new int[2, 2]; array[0, 0] = 1; Console.WriteLine(array[0, 0]); // The same reference can hold a different size of array. array = new int[3, 3]; array[2, 2] = 1; Console.WriteLine(array[2, 2]);
1 1
Arguments. A method may receive a 2D array by specifying the type of the elements. The dimensions are not used in the argument list—any 2D array of the correct element may be passed.
Tip Changes to elements in the argument will also affect the original version. Only the reference is copied to the new method.
Here The PrintFirstElement() method receives a 2D bool array. It then prints the value of the bool in the first row and first column.
using System; class Program { static void PrintFirstElement(bool[,] values) { // Display value of first element in first row. Console.WriteLine(values[0, 0]); } static void Main() { // Any array size of the right element type can be used. bool[,] values = new bool[100, 100]; values[0, 0] = true; PrintFirstElement(values); } }
True
Loops. 2D array loops are complicated. It is easy to cause errors related to invalid indexes. Here our 2D array is a four-element box, composed of two pairs.
Next To begin our for-loop, we acquire the upper bound of the zero dimension, and the upper bound of the first dimension of the array.
for
Warning The loop will not continue to work correctly if the array reference itself is modified or the array data is resized.
Note Nested loops are not always needed. In an array with 2 elements in each row, you can access positions 0 and 1 from a single for-loop.
using System; // Instantiate a new 2D string array. string[,] array = new string[2, 2]; array[0, 0] = "top left"; array[0, 1] = "top right"; array[1, 0] = "bottom left"; array[1, 1] = "bottom right"; // Get upper bounds for the array int bound0 = array.GetUpperBound(0); int bound1 = array.GetUpperBound(1); // Use for-loops to iterate over the array elements. for (int variable1 = 0; variable1 <= bound0; variable1++) { for (int variable2 = 0; variable2 <= bound1; variable2++) { string value = array[variable1, variable2]; Console.WriteLine(value); } Console.WriteLine(); }
top left top right bottom left bottom right
Add row, add column. You cannot add a new row or column to a 2D array—the array is fixed in size and a new array must be created to add elements. Here we introduce AddRow and AddColumn.
Info AddRow allocates a new 2D int array and copies the current array into the new one. It then copies a separate int array as a new row.
Next AddColumn allocates a new array with an extra column and copies the previous array. It copies an int array into a new column.
Note These methods do not "add rows or columns" to a 2D array. Instead they create a new array and add to that.
Tip For optimal performance, consider using a List and adding int arrays to that. Or add Lists of ints to a List in a 2D list.
using System; class Program { static int[,] AddRow(int[,] original, int[] added) { int lastRow = original.GetUpperBound(0); int lastColumn = original.GetUpperBound(1); // Create new array. int[,] result = new int[lastRow + 2, lastColumn + 1]; // Copy existing array into the new array. for (int i = 0; i <= lastRow; i++) { for (int x = 0; x <= lastColumn; x++) { result[i, x] = original[i, x]; } } // Add the new row. for (int i = 0; i < added.Length; i++) { result[lastRow + 1, i] = added[i]; } return result; } static int[,] AddColumn(int[,] original, int[] added) { int lastRow = original.GetUpperBound(0); int lastColumn = original.GetUpperBound(1); // Create new array. int[,] result = new int[lastRow + 1, lastColumn + 2]; // Copy the array. for (int i = 0; i <= lastRow; i++) { for (int x = 0; x <= lastColumn; x++) { result[i, x] = original[i, x]; } } // Add the new column. for (int i = 0; i < added.Length; i++) { result[i, lastColumn + 1] = added[i]; } return result; } static void Display(int[,] array) { // Loop over 2D int array and display it. for (int i = 0; i <= array.GetUpperBound(0); i++) { for (int x = 0; x <= array.GetUpperBound(1); x++) { Console.Write(array[i, x]); Console.Write(" "); } Console.WriteLine(); } } static void Main() { int[,] values = { { 10, 20 }, { 30, 40 } }; Console.WriteLine("CURRENT"); Display(values); // Add row and display the new array. int[,] valuesRowAdded = AddRow(values, new int[] { 50, 60 }); Console.WriteLine("ADD ROW"); Display(valuesRowAdded); // Add column and display the new array. int[,] valuesColumnAdded = AddColumn(valuesRowAdded, new int[] { -1, -2, -3 }); Console.WriteLine("ADD COLUMN"); Display(valuesColumnAdded); } }
CURRENT 10 20 30 40 ADD ROW 10 20 30 40 50 60 ADD COLUMN 10 20 -1 30 40 -2 50 60 -3
Error, cannot convert. A 2D array is not compatible with a 1D array—the types are different. So we cannot pass a 2D array to a method that accepts a 1D array (or the opposite case).
class Program { static void Main() { string[,] array = new string[10, 10]; Test(array); } static void Test(string[] example) { } }
error CS1503: Argument 1: cannot convert from 'string[*,*]' to 'string[]'
Benchmark, GetUpperBound. GetUpperBound is slow. Its result should be stored in a local variable. This benchmark shows the performance decrease with GetUpperBound.
Version 1 This code uses GetUpperBound 0 to loop over the rows in a 2D array. It stores the result of GetUpperBound in a local.
Version 2 This version uses the fact that each row has 2 elements, so it can derive the total row count from the Length divided by 2.
Result On .NET 5 in 2021, using the Length property for a loop boundary is faster than using GetUpperBound.
Benchmark
using System; using System.Diagnostics; using System.Runtime.CompilerServices; const int _max = 10000000; int[,] weights = new int[,] { { 100, 20 }, { 0, 0 }, { 5, 10 }, }; // Version 1: sum 2D array with GetUpperBound loop. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { int sum = 0; int top = weights.GetUpperBound(0); for (int z = 0; z <= top; z++) { sum += weights[z, 0] + weights[z, 1]; } if (sum != 135) { return; } } s1.Stop(); // Version 2: sum 2D array with Length-based loop. var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { int sum = 0; int count = weights.Length / 2; for (int z = 0; z < count; z++) { sum += weights[z, 0] + weights[z, 1]; } if (sum != 135) { return; } } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns"));
9.34 ns GetUpperBound 6.98 ns Length / 2
With initializer syntax, we can create 2D arrays. And then with nested for-loops we can iterate over them—it is easiest to use Length, but GetUpperBound is sometimes needed.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Nov 29, 2023 (new example).
Home
Changes
© 2007-2024 Sam Allen.