C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Part A: Here we initialize the 2D array with an initializer expression. Each element in this array is a string.
Part B: We use the indexing syntax to access elements. We use 2 indexes for a 2D array. Each dimension is indexed starting at zero.
Debugger: We can examine the code in the Visual Studio debugger. To the compiler, the string[,] array is a string[2, 2] array.
C# program that creates 2D array
using System;
class Program
{
static void Main()
{
// Part A: create 2D array of strings.
string[,] array = new string[,]
{
{"cat", "dog"},
{"bird", "fish"},
};
// Part B: access (and print) values.
Console.WriteLine(array[0, 0]);
Console.WriteLine(array[0, 1]);
Console.WriteLine(array[1, 0]);
Console.WriteLine(array[1, 1]);
}
}
Output
cat
dog
bird
fish
Note: GetUpperBound is probably not best for a simple 2D array, but for a larger array, it will work more reliably than other approaches.
C# program that uses GetUpperBound
using System;
class Program
{
static void Main()
{
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);
}
}
}
Output
AA, BB
CC, DD
And: If we take Length, which is 10, and divide by 2, we get 5. We can iterate until we reach 5.
C# program that uses length-based loop
using System;
class Program
{
static void Main()
{
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);
}
}
}
Output
ONE, TWO
THREE, FOUR
FIVE, SIX
Info: The performance of GetUpperBound can make an impact. But often, using jagged arrays (or flattened arrays) is the best solution.
Var: This keyword is used to reference the 2D array. This makes the syntax for the program simpler—var is often used with 2D arrays.
VarC# program that uses int array, GetUpperBound twice
using System;
class Program
{
static void Main()
{
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("--");
}
}
}
Output
ELEMENT: 200
ELEMENT: 400
--
ELEMENT: 2000
ELEMENT: 4000
--
ELEMENT: 20000
ELEMENT: 40000
--
Also: We can use a 2D array reference like int[,] to refer to any array size. The element type must match.
C# program that creates arrays, no initializers
using System;
class Program
{
static void Main()
{
// 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]);
}
}
Output
1
1
Tip: Changes to elements in the argument will also affect the original version. Only the reference is copied to the new method.
PrintFirstElement: This method receives a 2D bool array. It then prints the value of the bool in the first row and first column.
C# program that uses 2D array as argument
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);
}
}
Output
True
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.
ForCaution: 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.
C# program that loops over 2D string array
using System;
class Program
{
static void Main()
{
// 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();
}
Console.ReadLine();
}
}
Output
top left
top right
bottom left
bottom right
Here: We design a method (Handle) that receives an array reference. It then tests the Rank of the parameter array.
And: It handles both 1D and 2D arrays in the same method. It uses GetValue to access the array elements.
C# program that uses Rank
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;
}
}
}
Output
Rank: 1
1
2
Rank: 2
02
13
AddRow: This 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.
AddColumn: This 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.
C# program that adds row, column to 2D array
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);
}
}
Output
CURRENT
10 20
30 40
ADD ROW
10 20
30 40
50 60
ADD COLUMN
10 20 -1
30 40 -2
50 60 -3
C# program that causes cannot convert error
class Program
{
static void Main()
{
string[,] array = new string[10, 10];
Test(array);
}
static void Test(string[] example)
{
}
}
Output
error CS1503: Argument 1: cannot convert from 'string[*,*]' to 'string[]'
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: Using the Length property for a loop boundary is faster than using GetUpperBound.
BenchmarkBut: If we access GetUpperBound rarely, and store its result in a local, the performance loss is going to be small in many programs.
C# program that shows GetUpperBound performance
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
class Program
{
const int _max = 10000000;
static void Main()
{
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"));
}
}
Output
15.42 ns GetUpperBound
8.63 ns Length / 2
Tip: A List can solve problems that would otherwise require confusing 2D array resizing and copying.
So: Both parts are considered in determining type. Arrays are not all the same type.
Quote: The rank of an array is the number of dimensions. The type of an array (other than a vector) shall be determined by the type of its elements and the number of dimensions (The CLI Annotated Standard).