C# Simple, Rectangular, Mixed, and Jagged Arrays, Foreach Loops and Nested For Loops

Welcome to the 8th tutorial in the "C# for the Completely Uninitiated" series..

 

Source code used in this tutorial:

 

  • namesarray.cs
  • boundslength.cs
  • deptstore.cs
  • jobcandidates.cs
  • simplenested.cs
  • threed.cs





Single Dimension Arrays

An arrayis a collection of contiguous storage spaces in memory that are setaside to hold a group of variables of the same type. These individualvariables are accessed using the name of the array in conjunction withan index value specifying the offset into the array at which thevariable in question is located.

How's that for a mouthful, eh? Arrays can beconfusing to the uninitiated. But after a few examples I think you'llhave an "Aha!" reaction. Imagine that you are taking a group of kids ona field trip. If this scenario is painfully aversive, then substitutetaking a group of cheerleaders to the beach. It is your responsibilityto keep track of the names of everyone on the trip, because you have todo a head-count of the bus riders. This is a good time to use an array.Since names are strings of characters, it makes sense that we'd use astring array.

Now, admittedly, you could opt to use a separate string variable for each bus rider, i.e.,

string name1 = "Zoey";
string name2 = "Bryan";
string name3 = "Beth";
string name4 = "Carl";
string name5 = "Glenda";
string name6 = "Eric";
string name7 = "Frank";
string name8 = "Gary";
string name9 = "David";
string name10 = "Hubert"; //Poor guy; imagine how much he got picked on in school…
string name11 = "Helga"; //Probably Hubert's sister and partner in parental misfortune…
string name12 = "Mike";
string name13 = "Sarah";
string name14 = "Allan";

The above code is functional, but it is notsmart. The smart thing to do is to use the structure that C# providesfor handling this sort of data storage need: the array. To declare a string array and initialize it to contain these names, we'd do the following:

 

string[] names = {"Zoey","Bryan","Beth","Carl","Glenda","Eric",
"Frank","Gary","David","Hubert","Helga","Mike",
"Sarah","Allan"};

This is an example of a single-dimensionalarray (you'll learn about multidimensional arrays later). In C#, arrayindices start at zero. This means that in our names array, the first name, "Zoey", is held in the 0th element of the array. In other words…

Console.Write(names[0]);

…would write the name "Zoey" to the console. What name does names[5]hold? If you said "Eric", you're correct. Now, what I hope you'venoticed is that the first name is stored in element 0 of the array. The3rd name is in element 2, the 6th name is in element 5, etc. Sincearrays are zero-based in C#, the nth array item will be in the (n-1)thelement.

What if you wanted to write each of these names to the Console? You could type out a total of fourteen Console.WriteLine()statements, but that is laborious. Instead, it would be better totraverse the elements of the array one at a time using a loop. Forarrays, we have a special loop called a foreach loop. You can think of it like this: "For each element in the array, do the following…"

The format for a foreach loop is like this:

 

foreach(type iteration-variable in array_name){
//code that acts on elements of the array goes here
}

So, for our string array names, we'd use something like the following:

 

foreach(string name in names){
Console.WriteLine("t{0}",name);
}

As far as the compiler is concerned, itdoesn't matter what you name the variable that will reference eachelement of the array as we traverse the array elements using theforeach loop, but it does matter what array name you specify. Your foreach loop must reference an actual array that has been declared and initialized. So, for instance, we could also write:

 

foreach(string foo in names){
Console.WriteLine("t{0}",foo);
}

But we could not do this:

 

foreach(string foo in foobar){
Console.WriteLine("t{0}",foo);
}

That wouldn't compile. It would generate a syntax error because we haven't declared a string array named foobar.

Although you can use any name for theiteration variable, it's a best practice to only name it somethingmeaningful. In the loop shown above, I named my iterator variable name. This makes sense because the array itself is named names. So, in effect foreach(string name in names) is saying "For every name in the list of names…"

If you want to create a fixed-size arraywithout initially assigning any values to it, you can. For example,let's say that I wanted to create an integer array with twenty elementsto hold the grades of a classroom of students for a midterm exam. Icould create such an array like this:

integer[] MidtermGrades = new int[20];

Another way to do it is in two separate lines of code, like this:

 


int[] MidtermGrades;
MidtermGrades = new
int
[20];

Programming Assignment:create a C# console application that initializes a string array to holdthe fourteen names used in the field trip example above. Afterinitializing the array, the program should write each array element'svalue to the console using a foreach loop. Once you've made an honest attempt to do it yourself, you can look here if you need some hints on how to write this program.

Sample output:

In C#, an array is an object, and as youlearned in a previous tutorial in this series, to use objects we haveto instantiate a particular instance of the object in question. This iswhat is going on whenever you see the new keyword used in this fashion:

 

string[] strArray = new string[5]

In the line of code above, we areinstantiating an instance of a string array of fixed length that willhave five elements. We could also choose to initialize the array, likeso:

 

string[] strArray = new string[5] { "str1", "str2", "str3", "str4", "str5" };

When initializing an array on the same line as it is declared, you can omit the new keyword and the array type and brackets. This shortened form is equivalent to the line of code shown above:

 

string[] strArray = {"str1", "str2", "str3", "str4", "str5" };

Here, the C# compiler understands via context that we intend to instantiate a string array instance named strArray.Our assignment of values to the array's elements is what gives thecompiler the necessary context for understanding our intent, and makesthis shortcut possible. We assigned five strings, so obviously weintended to make this a fixed-length array of five elements.

And speaking of the length of an array, there is an easy way to tell exactly how many elements an array contains. The Array class contains a read-only property named Length. We can examine it anytime we want to know the total number of elements in an array. The GetLowerBound and GetUpperBoundmethods allow us to determine the index value of the very first arrayelement and the very last array element, respectively. To demonstrate:

This code…

 


using System;

class Program {

static void Main(string[] args) {

string[] strArray = { "str1", "str2", "str3", "str4", "str5" };
int lower = strArray.GetLowerBound(0);
int upper = strArray.GetUpperBound(0);
int length = strArray.Length;

Console.WriteLine("ntstring[] strArray = {"str1","str2","str3","str4","str5"};n");

Console.WriteLine("tLowerBound = {0} //strArray[{1}] holds the value "{2}"n",lower,lower,strArray[lower]);

Console.WriteLine("tUpperBound = {0} //strArray[{1}] holds the value "{2}"n", upper, upper, strArray[upper]);

Console.WriteLine("tArray length = {0} // i.e., there are five total elements (elements 0,1,2,3, and 4)n", length);

Console.Write("tTo exit program, press the Enter key… ");
Console.ReadLine();
}

}

produces this output…

 

 


 


 



 


 


 



Multidimensional (a.k.a. Rectangular) Arrays

Up until now, we've been talking about single dimensional arrays,simple arrays that are useful for things like lists of numbers orstrings. Single-dimensional arrays are the essence of simplicity, likea grocery list. Now, however, we're going to turn our attention tomultidimensional arrays, sometimes called rectangular arrays.

A multi dimension array is declared as following:

 

string[,] strArray;

After declaring an array, you can specify thesize of array dimensions if you want a fixed size array or dynamicarrays. For example, the following code two examples create two multidimension arrays with a matrix of 3×2 and 2×2. The next array can store6 items in groups of two each.

 


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

If you don't want to specify the size of arrays, just don't define a number when you call new operator. For example,

 


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

You can also omit the new operator as we didin single dimension arrays. You can assign these values directlywithout using the new operator. For example:

 


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

The most basic multi-dimensional array is anarray of an array, also referred to as two-dimensional. To create atwo-dimensional array, declare the array variable as we did earlier butadd a comma in the square brackets. The formula you would use is:

DataType[,] VariableName;The pair of brackets is empty but must contain a comma. There are twoways you can use a two-dimensional array. If you are declaring thearray variable but are not ready to initialize it, use the followingformula:

DataType[,] VariableName = new DataType[Number1,Number2];Based on this, type two integers separated by a comma in the right square brackets. Here is an example:

 


using System;

namespace CSharpLessons
{
class Exercise
{
static void Main()
{
string[,] Members = new string[2,4];
}
}

In this declarat

ion, the members arrayvariable contains two lists. Each of the two lists contains 4 items.This means that the first list contains 4 items, the second listcontains 4 items also. Therefore, the whole list is made of 8 items(2*4=8). Because the variable is declared as a string, each of the 8items is a string.

You can initialize an array variable whendeclaring it. To do this, on the right side of the declaration, beforethe closing semi-colon, type an opening and a closing curly brackets.Inside of the brackets, include a pair of an opening and a closingcurly brackets for each internal list of the array. Then, inside of apair of curly brackets, provide a list of the values of the internalarray, just as you would do for a one-dimensional array. Here is anexample:

 


using System;

namespace CSharpLessons
{
class Exercise
{
static void Main()
{
string[,] members = new string[2,4]{
{"Celeste", "Mathurin", "Alex", "Germain"},
{"Jeremy", "Mathew", "Anselme", "Frederique"}
};

Console.WriteLine();
}
}

If you use this technique to initialize anarray, you can omit specifying the dimension of the array. Therefore,the array declaration shown above could also be written like this,leaving out "new string [2,4]":

 


string[,] members = {
{"Celeste", "Mathurin", "Alex", "Germain"},
{"Jeremy", "Mathew", "Anselme", "Frederique"}
};

With two-dimensional arrays, we often need touse nested loops to access all elements. I've covered for loops in thepast, but not nested for loops. Let's code a simple example of nested loops in action. The source code shown herewill produce the following output, which indicates that the key tonested for loops is that for each iteration of the outer loop, theinner (or nested) loop iterates several times:

Now let's see if we can code a simple exampleof using nested loops with a rectangular array. Assume that there arethree job candidates, and that each candidate has a name, resume, and apersonal reference. Create a two-dimensional array to store thefollowing values, and then display those values on the console using anested for loop:

 


Mr. Johnson
– resume #1
– personal reference #1
Ms. Burton
– resume #2
– personal reference #2
Ms. Smith
– resume #3
– personal reference #3

Here is the source code that will produce the following output:

Programming Assignment:create a C# console application that creates three separatetwo-dimensional arrays. Using these three arrays, create data for threewomens' clothing articles, and data for three mens' or childrens'clothing items. Use a nested for loop to iterate across every element,printing information from each array to the console. Once you've made an honest attempt to do it yourself, you can look here if you need some hints on how to write this program.

To use the members of a two-dimensional array,you can access each item individually. For example, to initialize atwo-dimensional array, you can access each member of the array andassign it a value. The external list is zero-based. In other words, thefirst list has an index of 0, the second list has an index of 1.Internally, each list is zero-based and behaves exactly like aone-dimensional array. To access a member of the list, type the name ofthe variable followed by its square brackets. In the brackets, type theindex of the list, a comma, and the internal index of the member whoseaccess you need. Here is an example:

 

using System;

namespace CSharpLessons
{
class Exercise
{
static void Main()
{
String[,] members = new String[2,4];

members[0,0] = "Celeste";
members[0,1] = "Mathurin";
members[0,2] = "Alex";
members[0,3] = "Germain";
members[1,0] = "Jeremy";
members[1,1] = "Mathew";
members[1,2] = "Anselme";
members[1,3] = "Frederique";

Console.WriteLine();
}
}

Here's an example of a three-dimensional array.

Note to reader: you may have noticed that Iuse a lot of tab and newline escape characters in myConsole.WriteLine() invocations. This is merely a personal preference.I do it to offset the console output away from the top and left edgesof the console window. It's not necessary to do this. 


 


 



 


 


 



Jagged and Mixed Arrays

With a rectangular array, i.e., a multidimensional array, it's possibleto calculate exactly how many elements the entire array contains. Forexample, the following two arrays contains 20 elements and 70 elements,respectively:

 

int[,] MyIntArray = new int[5, 4]; //this is a two-dimensional array

int[, ,] My3DArray = new int[2, 7, 5]; //this is a three-dimensional array

By contrast, a jagged array's totalnumber of elements cannot be calculated as easily. A jagged array is anarray of arrays. Unlike the two multidimensional arrays shown above,the following array, which is a jagged array, has only one dimension.However, this one-dimensional array has three elements, and each ofthose elements is itself a single-dimensional array of integers:

int[][] jaggedArray = new int[3][];

Before you can make use of a jagged array, you have to initialize its elements. This could be done like this:

 

jaggedArray[0] = new int[5];
jaggedArray[1] = new int[4];
jaggedArray[2] = new int[2];

Each of the elements is a single-dimensionalarray of integers. The first element is an array of 5 integers, thesecond is an array of 4 integers, and the t

hird is an array of 2integers. It is also possible to use initializers to fill the arrayelements with values, in which case you do not need the array size. Forexample:

 

jaggedArray[0] = new int[] { 1, 3, 5, 7, 9 };
jaggedArray[1] = new int[] { 0, 2, 4, 6 };
jaggedArray[2] = new int[] { 11, 22 };

And here is another way we could initializethis jagged array. Here, we perform the initialization in tandem withthe array declaration:

 

int[][] jaggedArray = new int[][]
{
new int[] {1,3,5,7,9},
new int[] {0,2,4,6},
new int[] {11,22}
};

How would you make an assignment to replace the 11 in the third element above with the value 25?

Answer: well, 11 is the first element of the third array, so our code would be jaggedArrray[2][0];

Notice that, unlike with simple and multidimensional arrays, you cannot omit the newkeyword from the elements' initialization in a jagged array, becausethere is no default initialization for the elements. Why, you ask?Well, recall that the elements of a jagged array are themselves arrays. In C#, arrays are a reference type, and we have to instantiate instances of objects using the new keyword.

It is possible to mix jagged andmultidimensional arrays. The following is a declaration andinitialization of a single-dimensional jagged array that containstwo-dimensional array elements of different sizes:

 

int[][,] jaggedArray4 = new int[3][,]
{
new int[,] { {1,3}, {5,7} },
new int[,] { {0,2}, {4,6}, {8,10} },
new int[,] { {11,22}, {99,88}, {0,9} }
};

To my mind, however, when your data structureis so complex as to require such a mixed array, it's time to refactoryour code so that data can be handled by special hand-crafted classes,whose properties can be laid out in such a way that storing data in theproperties of instances of those classes is more intuitive.

As a closing note, let me say that, for manypeople, arrays are mind-boggling. It can take repeated exposure toarrays, over a considerable period of time, before you begin to "getit". If you find yourself struggling to wrap your mind aroundtwo-dimensional (or even simple) arrays, don't force yourself to pressonward and tackle jagged and mixed arrays. You have to have afoundation to build upon. Continue to seek out examples of simplerarrays, and practice manipulating them with for loops, or nested forloops.

 




Well, I hope that you've benefited, at least a little, from this tutorial. As ever, I welcome any feedback you may wish to impart. 


Twitter Digg Delicious Stumbleupon Technorati Facebook Email

No comments yet... Be the first to leave a reply!