Data Structures in C# Part 1: Arrays
Tags: beginners, programming, csharp, dotnet
Published: 2023-05-27 17:20:40

## Hey There 👋🏻
This post is the beginning of a series about **Data Structures** in general, C# is the language you'll see the coding examples in, but the concepts are mainly general concepts that even apply in other programming languages. However, I'll try my best to mention the differentiating points where the concept differs from one language to the other. 

> Make sure to check the end of each post in this series for some practice problems 

## So, Let's begin 🚀

**What are arrays?**
An array is a data structure that's used to store a fixed number of elements from the same data type. Say we have 10 variables of type **int**, instead of having to declare 10 variables, we can instead use an array of type int, and store 10 numbers inside it.
The **elements** of an array are stored in contiguous slots in the memory, each element has an **index**, which we'll talk about later.

**How do we declare an array in C#?**
Declaring an array is very simple, like variables, we first specify the data type of the values we want to store in our array, then we use the square brackets **[]** to indicate that this is an array and not a normal variable, then we give it a name, and that's an array declared in C#. Check the following code snippet:

`int[] numbers;`
This is the declaration part, but our array has no values, let's see how we can **initialize** it.

**1:** First declare the array, then initialize it later.
**2:** We can initialize an array upon declaration.

## 1:
In the previous code snippet, I declared a **numbers** array but I haven't initialized it. So, let's see how we can do that in a separate step:

```

int[] numbers;

numbers = new int[5];

```

Now our array is initialized to an empty array, the 5 is the length of the array, and since we didn't provide values for the elements in our array, the 5 elements will be assigned the default value of their data type, **int** is a **value type** thus all the values will default to **0**. If my array was of the **string** data type, the values would've rather defaulted to **null** as it's the default value for **reference types**.

## 2:
We can declare and initialize all in one step, like this:

`int[] numbers = {0, 50, 100, 150, 200};`

OR

`var numbers = new int[] {0, 50, ...}`

**What's the index of an element?**
An index is like an address for the element, each element in the array has an index so that elements could be accessed through their indexes. Arrays in most programming languages are **zero-indexed**, which means that the indexing starts at 0, so the first element in the array doesn't sit at index position 1, rather it's index position 0, the second is at position 1, third at 2 and so on...
In C#, we use the square brackets to get an element at a particular index, like say we want the first element, we'll use this notation:

```

Console.WriteLine(numbers[0]);
//OUTPUT: 0
//Because we haven't assigned it any value so it's outputting the default value.

```

Now that we know what the index is, let's assign values to elements at different positions in our **numbers array**.

```

numbers[0] = 0;
numbers[1] = 50;
numbers[2] = 100;
numbers[3] = 150;
numbers[4] = 200;

```

I've now assigned each element in the array a value. 
If you recall, our array had a length of 5, but the last index position is 4, why? Well, because indexing starts from 0. Keep that in your mind.

**The length property of arrays**
In most programming languages, there's a **length** property, so that we can access the length of a specific array.
Let's see that in C#

```

Console.WriteLine(numbers.Length);
//OUTPUT: 5

```

> **💡 Quick Tip**: The index of the final element equals the length of the array - 1.

If you recall, I did the assignment of each element separately. Like `numbers[0] = 0` and the like.

You know how we could make that less tedious?
If **for loops** was your answer, then you're 100% correct.

I've removed the previous assignment operations, and replaced them with a for loop, just as follows:

```

for (int i = 0; i < 5; i++)
{
    numbers[i] = 50 * i;
}

//This loop is just for printing out the values.
foreach(int number in numbers)
{
    Console.Write($"{number} ");
}
//OUTPUT: 0 50 100 150 200

```

Ignore the **foreach loop** here, focus on the first loop.
We're initializing **i** to 0. 
<u>REMEMBER, INDEXING STARTS AT 0</u>
Our loop keeps going until **i** is less than 5, which recall, is the length of our array. Now if we go back to when we first initialized our array, and we change it to this:
`numbers = new int[4];`
Just changed the 5 to a 4, now if you run the code, you'll get an exception

> Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.

But why? All we've done was just changing the length of our array, how did that tiny change break our program?
The answer is, we **hardcoded** the length of our array into the condition inside the for loop.
At first, our length was in fact 5, so our condition would end once we reach the final element in our array, which had the index 4, thus **4 < 5** is the final true expression, then afterwards we break out of the loop. Put simply, we haven't exceeded the bounds of our array, we didn't go beyond the index of the final element.

after changing its length to 4, the final element had an index of 3, but we attempted to assign numbers[4] a value, which basically doesn't exist as the last element is numbers[3], thereby our code broke down and we got that exception. 

The moral of this is that you should never hardcode the length of your array. Always use the length property, so that if the array changes, the code wouldn't fail as the length value will be altered dynamically.

Let's fix the for loop condition so that it doesn't break anymore:

```

for(int i = 0; i < numbers.Length; i++)
{
    numbers[i] = 50 * i;
}

```

And now even if the array changes, the code will still work properly.


**Modifying array elements**
To modify an array element, we use its index, then we give it a different value. In our **numbers** array, I'd assigned the first element a value of 0, but now I changed my mind and I want to make it 10 for instance, I could do that simply as follows:

`numbers[0] = 10;`

That's it, I've just modified an element inside an array.


## What types go inside an array?
To answer this question, we must make a necessary distinction. In statically typed programming languages, arrays store elements of the same type, and arrays have a fixed size which should be known by the programmer beforehand. However, this is not the case in all programming languages, for instance, in **Javascript**, arrays can store values of different types, additionally, arrays could grow and shrink.
In C#, it's possible to create that type of **dynamic array** that can store elements of multiple types, like ints, doubles, strings, objects and even user defined types. This collection is known as an **ArrayList**, its size isn't fixed too. You're allowed to add/remove elements from it on the go.

The ArrayList data type isn't recommended in C# as it's not **type-safe**, meaning that by storing values of various types could potentially cause runtime errors, take this for example:

```

ArrayList list = new ArrayList();
Person person = new Person();

list.Add(100);
list.Add(person);

int number = (int)list[1];

```

> Assuming we have a **Person** class
This will throw a runtime error as we can't cast a person to an int, it doesn't make sense.

The **generic List<T>** is the option to go with if you want a type-safe dynamic collection of items, more on it in a later post.

## The different types of arrays in **C#**
In C#, there're 3 types of arrays:
**1:** Single-dimensional arrays 📌
**2:** Multi-dimensional arrays ⚛️
**3:** Jagged arrays 🎡

**Single-dimensional arrays**: As the name says, has one dimension.

**Multi-dimensional arrays**: Can have multiple dimensions, think of it like a grid, with rows and columns.

**Jagged arrays**: Sounds fancy? This type is ultimately an array of arrays, an arrays whose elements are arrays. 😁

In this post we'll be primarily focusing one on type which in reality, the most commonly used type, that being the **Single-dimensional array**. Let's look at some built in C# methods and properties for arrays.

## Built-in C# array methods and properties 

**1:** Array.Sort(): This method is used to sort array elements, here's an example:

```

double[] numbers = { 10.9, 1.99 , 0.82 , 6.99 };
Array.Sort(numbers);

//AFTER SORTING: 0.82 1.99 6.99 10.9

```

**2:** Array.Reverse(): This method reverses the order of which elements are arranged inside the array.

**3:** Array.IndexOf(): Searches for a given object and returns the index of its first occurrence in the given array. Example:

```

double[] numbers = { 10.9, 1.99 , 0.82 , 6.99 };
Console.WriteLine(Array.IndexOf(numbers, 6.99));

//OUTPUT: 3

```

**4:** Array.Copy(): This method is used to copy a range of values from one array(**Source array**) to another array(**Destination array**) for a specified length.

```

double[] numbers = { 10.9, 1.99, 0.82, 6.99 };
double[] firstTwo = new double[2];

Array.Copy(numbers, firstTwo, 2);

foreach (double number in firstTwo)
{
    Console.Write($"{number} ");
}

```
**5:** Array.Rank: This property gets the number of dimensions of an array aka **rank**.

**6:** Array.Length: You've already seen this one in action, we use it to get the number of elements inside of an array.



## Practice questions ✍️
Here are couple of questions that you can solve to practice your array and problem solving skills.

## Tips
> 💡 You can find my answer to the first problem down in the comments section!

> 💡 If you get stuck, use some tool to get help (i.e Bing Ai), but make sure to have a go at it first, and if you get partially stuck with some small issue, be specific with your issue and then continue the rest on your own.

> 💡 Try jotting down a brief explanation of your solution after completing a question so that you're always reminded of how you implemented the solution.

**1:** Reverse an array of integers
_Input: {1, 2, 3, 4, 5} 
 Output: {5, 4, 3, 2, 1}_

**2:** Find the sum of elements of an integers array
_Input: {5, 20, 18} 
 Output: 43_

**3:** Find the average of all the elements in an array
_Input: {7, 9, 5, 11} 
 Output: 8_

**4:** Find the largest element in an array 
_Input: {2, 5, 1, 10, 6} 
 Output: 10_

**5:** Find the smallest element in an array 
_Input: {2, 5, 1, 10, 6} 
 Output: 1_


## Good luck, and have fun 😃