How To Use Arrays – C#

Join the Discord. Talk about Game Dev. Talk about Gaming.

What Is An Array

Arrays are very common in game development and something I used frequently in my game Puzzledorf to store information. One example is that I store the position of every object in the puzzle below in an array, so they’re useful, especially for creating an undo function.

The best way to picture an array is to think of it as a series of boxes, all in a row. Each box holds a variable, but all of the same type. Below is an example:

Array Example 1

If we wanted to store an array of integers, or int’s, it might look like this:

Int Array Example 1

The index is the unique label assigned to each box, in numbered order, and always starting at 0. In the above example, we have 5 boxes, so our array has a size of 5, however the labels, or indexes, go from 0 to 4.

How To Access Array Elements

To access the variable in a particular box (the boxes are more formally referred to as elements) we do so like this:

array[0] = 40;

The above line of code would change the first box in our array, the box labelled 0, or in proper programming speak, the box with an index of 0, into a value of 40, so that it would be like the example below:

Int Array Example 2

Likewise, we can access any box in our array in the same way:

array[4] = -1;
array[3] = 307;
array[1] = 208;

Which would change our array into this:

Int Array Example 3

But what if we want to read the information stored in our array and do something with it? We just do this:

int score = array[3];

If we did that, our variable int score would be equal to whatever value is stored in box 3 of our array, in this case, 307.

Of course, we couldn’t do this:

string highScore = array[3];

Because the variables in the array in our example are all int’s, you can only use them with other int variables (unless you do a conversion which is another whole topic).

Furthermore, you can access array elements by using a variable as the index. For example:

int index = 1;
array[index] = 300;

That would change our array as follows:

Int Array Example 3b

You can only use int variables as an index. You can’t use floats, unless you convert them to int’s. So you can’t do:

float index = 1;
array[index] = 300;

You should get an error saying something like “Cannot implicitly convert type ‘float’ to ‘int'”. In other words, the index of an array is always an int, and can’t be otherwise. You could convert the float, to an int:

float index = 1;
array[(int)index] = 300;

But variable type conversion is a whole other subject.

How To Create Arrays

When you want to create array, you create it like this:

int[] scoresArray = new int[10];

In other words:

dataType[ ] nameOfArray = new dataType[size];

First you have to declare what type of data, or variable, you will be storing in the array. In our example it is the type int.

The two [] after our data type means that this will be an array – it helps to think of them as a little box, like the little boxes that our array is made up of.

string[] is an array of strings, float[] is an array of floats, etc.

Then we name the array, just like with any variable, so we can refer to it later, in this case, scoresArray. 

Then we have to declare that we are making a new array, at which point we repeat what type of data the array is storing, but this time, we put a number inside our box [size]. This number just means how many boxes we want our array to have. In the above example, we said 10, so it would look like this:

Array Size Example 1

Remember that arrays start at 0, so although our size is 10, the last box is labelled 9. Each box also says empty, because when we create our array, nothing is inside the boxes. The actual value isn’t empty, but rather it is referred to as null.

Array Size Example 2

If we gave our array a size of something else, like [7], it would look like this:

int[] scores = new int[7];

Array Size Example 3

You can also fill the array with data at the same time as you create it. There are two ways:

int[] scoresArray = new int[] {1, 2, 3, 10, 4, 11};

In the above example, we don’t declare the size of the array, we just fill it with int’s. This would actually create an array of the same size as the number of values that we put into it, in this case, the size would be 6.

We can also do this:

int[] scoresArray = new int[6] {1, 2, 3, 10, 4, 11};

We can declare the size of the array and give it values at the same time. The reason you might do it that way is to make sure you don’t accidentally make the array bigger than intended.

Array Bounds

You may have wondered what happens if you try and use the index of a box that doesn’t exist. For example, in the array above, if we did the following:

scoresArray[9] = 10;

We would get an error because that box doesn’t exist. Likewise if we tried:

scoresArray[-1] = 10;

We would also get an error because that box doesn’t exist either, arrays always start at 0.

The most common errors from working with arrays are trying to access a box that isn’t there.

Accessing Empty Elements

Another common error is if you try and access a box in an array that has nothing in it. Take the following array example:

Int Array Example 4

If you tried use the variable stored in box 6: 

int highScore = scoresArray[6];

you would get an error, because it is null – there is no int stored in box 6. However, if you tried to store something in box 6, you would get no error:

scoresArray[6] = 1000;

Then once you have stored something in the box, you can read from it.

This is why sometimes when people use arrays they will do an if check to make sure that the array box, also known as an array element, is not null. Something like the following:

if( scoresArray[6] != null)
{
  highScore = scoresArray[6];
}

If you don’t understand the ! symbol, known as logical NOT, look at my article on logical operators.

How To Get An Array’s Size

If you want to find out how big an array is, that’s simple:

int arraySize = arrayName.Length;

You just call the name of the array, followed by the Length property, arrayName.Length. This will give you the full size of the array.

Int Array Example 2

If you want to access the last box in an array,  you can’t just get the size. If we got the length of the above array, it would be 5. But there is no box 5, so we would get an error if we tried:

array[5] = 10;

So then how can we always be sure to get the last box in our array, without knowing beforehand how big the array is? Simple.

int lastIndex = array.Length - 1;
array[lastIndex] = 10;

The last box in array, or the last element in an array, will always be one less than the size of the array, or, array.Length – 1;

How To Loop Over Arrays

If you are not familiar with loops, look here.

You might want to loop over every element in an array, for example, if you had an array of scores, and you wanted to find the high score, the simplest way would be to use a for loop:

for(int index = 0; index < scoresArray.Length; index++)
{
   if(scoresArray[index] > highScore)
   {
      highScore = scoresArray[index];
      break;
   }
}

Remember that to access the last element in an array, you use:

int lastIndex = array.Length - 1;

In our loop, we keep increasing index while it is less than the length of the array, meaning, it will stop at the last element in our array, giving us the same value as lastIndex above.

The word break in the above example will literally break out of the loop, or stop the loop at that point. In the above code example, once we found a score that was higher than our previous high score, the loop would stop (which probably isn’t what you would really do, you’d want to compare all scores, but it’s an example).

You can also use the word continue to keep a loop going, but to skip the rest of the code on that iteration through the loop, and start the loop again at the next index. Every time you go through a loop, that is considered a single iteration. Example:

for(int index = 0; index < scoresArray.Length; index++)
{
   if(scoresArray[index] > highScore)
   {
     highScore = scoresArray[index];
     continue;
   }
   Print("No high score found at index " + index);
}

Assuming the function Print() prints text to the screen, in the above code example, if we found a new high score, continue would stop the text printing to the screen. If you want to see it in action to help you picture it, use the following code sample in a C# console project (Unity example below that):

int highScore = 100;
int[] scoresArray = new int[3];
scoresArray[0] = 1;
scoresArray[1] = 200;
scoresArray[2] = 30;

for (int index = 0; index < scoresArray.Length; index++)
{
  if (scoresArray[index] > highScore)
  {
    highScore = scoresArray[index];
    continue;
  }
  Console.WriteLine("No high score found at index " + index);
}

Console.ReadKey();

Console.WriteLine() will print text, Console.ReadKey() will pause the application until a key is pressed on the keyboard. You can also use Console.Read() to completely halt the application.

If you want to test it in Unity, get rid of Console.ReadKey() and replace Console.WriteLine() with Debug.Log(“Text here”);

You will print out:

No high score found at index 0
No high score found at index 2

It would skip index 1, because of continue.

How To Copy And Duplicate Arrays

It’s no simple task to copy an array. You can’t just do:

array2 = array1;

I will demonstrate why. Try the following code sample:

string[] creatureNames1 = new string[4] { "Dragon", "Orc", 
"Mammoth" ,"Slime" };
string[] creatureNames2 = creatureNames1;
creatureNames2[0] = "Dire Wolf";

Console.WriteLine("Creature Names 2:");
Console.WriteLine(creatureNames2[0]);
Console.WriteLine(creatureNames2[1]);
Console.WriteLine(creatureNames2[2]);
Console.WriteLine(creatureNames2[3]);

Console.WriteLine("");
Console.WriteLine("Creature Names 1:");
Console.WriteLine(creatureNames1[0]);
Console.WriteLine(creatureNames1[1]);
Console.WriteLine(creatureNames1[2]);
Console.WriteLine(creatureNames1[3]);

Console.ReadKey();

Don’t forget to swap our Console commands for Debug.Log in Unity.

If you run that code, you will see that when we change element [0] in creatureNames2 from “Dragon” to “Dire Wolf”, it changes element [0] in both arrays.

This is because when you create an array, each element has a specific place it is stored in the devices memory, a place that has a specific address, eg, 1x000AC or something like that. It’s just like your home address.

When you say array1 = array2, rather than copying the information from one array over to the other, you are in fact copying the memory addresses of where information is stored in array1 into array2. 

This is because array1 and array2 are not in fact actual copies of the array, but references to where the array is stored in memory – they are more like address labels to stick on an envelope, containing the address of where you live, but your house is actually somewhere else.

It’s like a Google Doc – a document that is online, up in the cloud, and sharing it with two friends. They can both work on it at the same time, online, on two different computers, but if they make changes, they are both changing the same document.

The solution is this:

string[] creatureNames1 = new string[4] { "Dragon", "Orc", 
"Mammoth" ,"Slime" };
string[] creatureNames2 = new string[4];

for(int index = 0; index < creatureNames1.Length; index++)
{
  creatureNames2[index] = creatureNames1[index];
}

Console.ReadKey();

First of all, we create our creatureNames1 array. Then we create our creatureNames2 array.

When we use the word new, we are in fact saying that we want to store this array at a new memory address. So at the moment, creatureNames2 is an array that is stored at it’s own unique address. As soon as we go:

creatureNames2 = creatureNames1;

If we did that, creatureNames2 would no longer have a unique address, but will have the same array address as creatureNames1, because we are copying the arrays address, not the array.

This is why instead we create a loop, and loop over every element of both arrays, and uniquely assign each element of creatureNames1 to the corresponding element in creatureNames2 through using the same index. When we do this, creatureNames2 still has its own unique address, but it now has the same information as creatureNames1.

How To Resize Arrays

If you expect to be resizing your arrays, you’re better off using an alternative to arrays like Lists which do it all for you. However, below is how you resize an array.

Once an arrays size is set, you can’t easily change it manually. You in fact would have to copy the array elements first to a temporary duplicate array, then resize the array and copy the elements back. Example:

string[] creatureNames1 = new string[4] { "Dragon", "Orc", 
"Mammoth", "Slime" };
string[] oldCreatureNames = new string[creatureNames1.Length];

// COPY OLD NAMES TO DUPLICATE ARRAY
for (int index = 0; index < creatureNames1.Length; index++)
{
  oldCreatureNames[index] = creatureNames1[index];
}

// RESIZE
creatureNames1 = new string[6]; 

// COPY NAMES BACK TO RESIZED ARRAY
for (int index = 0; index < oldCreatureNames.Length; index++)
{
  creatureNames1[index] = oldCreatureNames[index];
}

// ADD NEW NAMES 
creatureNames1[4] = "Baboon";
creatureNames1[5] = "Dire Wold";

Console.WriteLine("");
Console.WriteLine("Creature Names 1:");
Console.WriteLine(creatureNames1[0]);
Console.WriteLine(creatureNames1[1]);
Console.WriteLine(creatureNames1[2]);
Console.WriteLine(creatureNames1[3]);
Console.WriteLine(creatureNames1[4]);
Console.WriteLine(creatureNames1[5]);

Console.ReadKey();

I put some comments in but: First we create our initial array creatureNames1, then we create a duplicate array to store all of the old names called oldCreatureNames.

We then loop over oldCreatureNames to copy the names over from creatureNames1.

We then use new again on creatureNames1 to create a brand new array, stored at a different memory address, that is now bigger than what it was previously. It now has a length of rather than 4.

We then copy all of the old names back into the now resized creatureNames1 array.

Finally we add two new creature names to the array and print them all out.

What Are Multi-dimensional Arrays

So far what we have been looking at are called one dimensional arrays, or 1D arrays. But there are also multi-dimensional arrays, most commonly, 2D and 3D arrays.

A 1D array is just a single row of boxes, as we’ve looked at:

Int Array Example 1

A 2D array, however, looks more like an except spread sheet; it has rows and columns, like this:

2D array example 1

In the above example, we have a 2D array of strings which are monster names. Generally these are reffered to as X index for Rows, and Y index for Columns.

The best way to think of a 3D array is like a Rubix Cube, or a series of 2D arrays. It has both rows and columns, which is the X and Y, but also a Z index, which puts one 2D array below another. Below is an example of a 3D array:

3D Array Example

What looks like multiple 2D arrays is actually a single 3D array. It is a shop inventory, and each different 2D array represents a type of item that the shop has in stock. Each separate 2D array is stored on a Z index, which I have labelled Z 0, Z 1, Z 2 to make it clearer.

I’ll go into a bit more detail on 2D and 3D arrays below.

How To Create A 2D Array

You create a 2D array like follows:

string[,] monsterNames = new string[3,3];

You can see how that is similar to declaring 1D arrays, except this time we have a comma in the middle. Left of the comma is X for rows, and the right is Y for columns,
or [x, y]. The above line of code would create a 2D array like our above examples, except it would be empty:

2D array example 2

We can fill the array when we create it like so:

string[,] monsterNames = new string[2, 2] { { "Dragon", "Wolf" }, 
{ "Slime", "Goblin" } };

Above is one line of code. It would give us the following array:

2D array example 3

[2, 2] means has a size of 2, and y has a size of 2. You could also declare it without declaring the size, just giving it values:

string[,] monsterNames = new string[,] { { "Dragon", "Wolf" }, 
{ "Slime", "Goblin" } };

C# will work out how many values you put into the array, and adjust the size accordingly. If you want to try it out, you can test this code in your C# console project:

string[,] monsterNames = new string[2,2] { { "Dragon", "Wolf" }, 
{ "Slime", "Goblin" } };

Console.WriteLine(monsterNames[0, 0]);
Console.WriteLine(monsterNames[0, 1]);
Console.WriteLine(monsterNames[1, 0]);
Console.WriteLine(monsterNames[1, 1]);
Console.ReadKey();

Again, to test it in Unity, replace Console.WriteLine with Debug.Log and remove Console.ReadKey().

If you test it, it will print out:

Dragon
Wolf
Slime
Goblin

So you can see that when you declare initial values in a 2D array, it assigns them to each row at a time, starting at X index 0 and  Y Index 0, finishing at X index 0 and Y index End, that being an entire row, then moving on to the next row, starting at X index 1 and Y index 0, etc.

How To Access Elements in a 2D Array

As the above code example demonstrated, you access the elements in a 2D array in almost the same way as with a 1D array, except you have to specify both the X and Y index in the array.

2D array example 3

You can see the relative indexes above. To get the cat:

monsterNames[0, 0];

To get the Hamster:

monsterNames[1, 1];

How To Create A 3D Array

You create a 3D array in a similar way to 2D arrays. Let’s look at creating a shop inventory again.

string[, ,] shopInventory = new string[3, 2 , 2];

That would give us an empty 3D array in the order [z, x, y]. To prefill it:

string[,,] shopInventory = new string[3, 2, 2]
  {{ "Sword", "Axe"} , { "Club", "Sickle"}},
  {{"Small Potion", "Large Potion"}, {"Strength Potion", "Defense Potion"}}, 
  {{ "Melon", "Berry"} , { "Nut", "Juice"}} 
};

It works similar to the 2D array, with with an extra layer of { } curly braces. Remember that 2D arrays fill in order of each row of X at a time, ie, x-0 y-0, x-0 y-1, etc. 3D arrays fill the same way, but starting with z-0, then z-1, then z-2, etc.

The first outer { } are to signify the bounds of the array.

Then each line in the above code example signifies one index, with the {} braces meaning z-…, and the inner sets of curly braces signifying each x-row.

Here’s a picture of what the above code creates:

3D Array Example 2

Accessing Elements of a 3D Array

You can print it out for yourself to see:

// PRINT
Console.WriteLine("Weapons / Z 0: ");
Console.WriteLine(shopInventory[0, 0, 0] +", " + shopInventory[0, 0, 1]);
Console.WriteLine(shopInventory[0, 1, 0] + ", " + shopInventory[0, 1, 1]);

Console.WriteLine("");
Console.WriteLine("Potions / Z 1: ");
Console.WriteLine(shopInventory[1, 0, 0] + ", " + shopInventory[1, 0, 1]);
Console.WriteLine(shopInventory[1, 1, 0] + ", " + shopInventory[1, 1, 1]);

Console.WriteLine("");
Console.WriteLine("Food / Z 2: ");
Console.WriteLine(shopInventory[2, 0, 0] + ", " + shopInventory[2, 0, 1]);
Console.WriteLine(shopInventory[2, 1, 0] + ", " + shopInventory[2, 1, 1]);
Console.Read();

We access the elements in a 3D array the same as other arrays, just remembering to do it in the order [z, x, y].

Looping Over 2D and 3D Arrays

You loop over 2D and 3D arrays in the same way you do with 1D arrays, you just have to nest one loop inside another. Here is an example to print out our shop inventory but with loops:

const int zSize = 3;
const int xSize = 2;
const int ySize = 2;

//3D Array
string[,,] shopInventory = new string[zSize, xSize, ySize] 
{ 
{{ "Sword", "Axe"} , { "Club", "Sickle"}},
{{"Small Potion", "Large Potion"}, {"Strength Potion", "Defense Potion"}}, 
{{ "Melon", "Berry"} , { "Nut", "Juice"}} 
};

for(int z = 0; z < zSize; z++)
{
  for(int x = 0; x < xSize; x++)
  {
    for(int y = 0; y < ySize; y++)
    {
      Console.WriteLine(shopInventory[z, x, y]);
    }
  }
}

Console.Read();

We use a const int to set the size of our array this time. A const variable is one that never changes. You can’t use a regular int to set the size of an array, because int‘s can change, and the size of the array can’t. It’s also better coding practice to use variables to set the array size, because we can re-use those values elsewhere in our code, like working out how many times to run our loop.

We then run 3 nested loops: we start looping over the z index of our array, then the y index, then the x index. This will print out every element in our 3D array in order.

You have to loop over arrays in the same order that you input the values, meaning, we input our values in [z, x, y] so we have to loop in that order, [z, x, y]. If you tried looping in some other order like [x, y, z],  you would get errors, going out of bounds of the array and trying to access things that aren’t there.

Other Types of Arrays

There are other types of arrays, such as jagged arrays, Lists and unordered maps, but they are covered elsewhere.

Join the Discord. Talk about Game Dev. Talk about Gaming.

3 thoughts on “How To Use Arrays – C#

Add yours

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: