Wednesday, 29 July 2015

C# program that creates 2D 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
Nested loops. These are not always necessary. For example, if you are using a 2D array with only two elements in each row, you can index into positions 0 and 1 from a single for-loop.

Performance. GetUpperBound is slow. You may not want to call it often. I took a benchmark comparing one million repetitions. It shows the performance decrease with GetUpperBound.
Thus: Using the Length property for a loop boundary is faster than using GetUpperBound.
Benchmark
Memory: I have also tested the memory usage of jagged and 2D arrays. This helps us determine which one to use.
Jagged vs. 2D Array
2D array benchmark result

Looping with GetUpperBound: 142 ms
Looping with Length/2:       47 ms
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: It handles both 1D and 2D arrays in the same method. It uses GetValue to access the array elements.
C# 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
Arguments. We can use 2D arrays as arguments. The 2D array will be passed as a reference, which means changes to it will also affect the original version.
Thus: The reference itself will be copied, but not the data to which it points.

Dimensions. In C# we can also specify arrays with more than two dimensions. We can use another comma in the indexing syntax. It will work as expected.
Multidimensional Array
Lists. You can use the generic type List to simulate a jagged or 2D List that is dynamically resizable. The syntax for this nested type is somewhat more confusing.
Nested List
Tip: This can solve problems that would otherwise require confusing 2D array resizing and copying.

Jagged array. An array element can have any type. This includes other arrays. With an array of arrays, we construct a jagged array—this gives us great flexibility.
Jagged: Array of Arrays
Research. In the CLI standard, I found material about the types of arrays. The Framework determines the type of an array by its rank (dimension count) and its element type.
So: Both parts are considered in determining type. Arrays are not all the same type.
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
2D arrays have many uses. And they can be used in many ways: we showed several indexing approaches. It is easiest to use Length, but GetUpperBound is sometimes needed.

A review. We created 2D arrays and looped over them. We mutated them. We benchmarked them. Before you use 2D arrays, research jagged arrays. These can improve the clarity and speed of code.

No comments:

Post a Comment