In the previous tutorial, Sanitizing user input, we sanitized the user input parts of
our calculator in C# .NET. In today's lesson, we're going to introduce you all
to the array data structure and show you what it's capable of accomplishing.

Array

Imagine that you want to store some information about multiple items, e.g.
you want to keep 10 numbers in a memory, each of the fields of a checkerboard or
names of 50 users. Perhaps you realize that there must be an easier way than to
start typing variables like user1, user2 ... up until user50. Despite the fact
that there may be 1000 of them. How would go about searching for something in
there? Definitely not like that!

If we need to store a larger amount of variables of the same
type, we can solve this problem using an array. We can imagine it as a
row of boxes, each of them containing one item. The boxes are numbered by
indexes, the first one has index 0.

(We see an array of 8 numbers on this
picture)

Programming languages are very different in the way they work with arrays. In
some languages (especially older ones, compiled), it wasn't possible to create
an array with a size specified at runtime (e.g. to specify its size using some
variable). Arrays had to be declared with a constant size in the source code.
They made a workaround by inventing pointers and custom data structures, which
often lead to errors in manual memory management and to program instability
(e.g. in C++). On the other hand, some interpreted languages allow us to not
only declare arrays of any size but to also change the size of an existing array
(it's possible e.g. in PHP). We know that C# is a virtual machine, which is
something between a compiled language and an interpreted language. Therefore, we
are able to declare an array with a size which we can enter during the runtime,
but once an array is created, its size can't be modified. Of course, we can work
around it or use other data structures, but we'll get to that later.

You might be wondering why we're dealing with arrays when they evidently have
some limitations and there are better data structures out there. The answer is:
"Arrays are simple". I don't mean that they're easy for us to understand, which
they are, but it's simple for C#. Working with arrays is fast since the items
are simply stored in memory as a sequence (next to each other), and every item
occupies the same amount of space and is quickly accessible. Many internal .NET
functions work with arrays somehow or return them. It is a key data
structure.

We use loops for the mass handling of array items.

We declare an array using brackets:

int[] numbers;

Numbers is obviously a name of our variable. Now, however, we've
just declared that the variable numbers is an array of integers.
Now we have to initialize it so we could use it. We'll use the
new keyword which we won't explain for now. Let's just be glad
knowing that that's how it is because arrays are reference data types (can be
understood as complex types):

int[] numbers = newint[10];

Now we have an array of a size of ten ints in the variable
numbers.

The array items can be accessed through brackets. Let's store the number 1 in
the first index (index 0):

int[] numbers = newint[10];
numbers[0] = 1;

Filling arrays manually like this would be too laborious. Let's use a loop
and fill an array with numbers from 1 to 10. We'll use a for loop to do just
that:

Note that the array provides the Length property, where its length is stored,
which is the number of its items.

Console application
1 2 3 4 5 6 7 8 9 10

We can also use a simplified version of the loop to work with collections,
known as foreach. It iterates over the items in the array and detects the length
of an array by itself. Its syntax is the following:

foreach (datatype variable in collection)
{
// commands
}

The loop iterates over the items in the collection sequentially, from the
first one to the last one. "Collection" is the general term for structures that
contain multiple items, which in our case is an array. The current item is
stored in the variable in each iteration of the loop.

Let's rewrite our existing program and use foreach. Foreach does not
have a control variable, so it's not suitable for the creation of our
array. We will primarily use it for printing.

Of course, we can also fill an array manually, even without accessing each
index gradually. We'll use curly brackets and separate items by commas:

string[] simpsons = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};

Arrays are often used to store intermediate results, which are used later in
the program. When we need some result 10 times, we won't calculate the same
thing 10 times, instead, we'll calculate it once and put it into the array, then
we just read the result.

The Array class methods

.NET provides the Array class for us which contains helpful methods for
working with arrays. Let's look at them:

Sort()

As the name suggests, the method will sort our array. Its only parameter is
the array that we want to sort. It is so clever that it works according to what
we have stored in the array. Strings are sorted alphabetically i.e. numbers
depending on its value. Let's try to sort and print our Simpsons family:

IndexOf() and LastIndexOf()

These methods return the index of the first or last occurrence of an item. If
they don't find the item, they return -1. Each method takes two parameters, the
first is an array, the second is the item we're searching for. Let's allow the
user to enter the name of a Simpson's character and tell them at what position
he/she is stored. It won't be very useful for us now since all we've got in our
array are strings; however, it'll be very useful for us when adding complex
objects in the array. Just keep in mind that that's a possibility until
then.

{CSHARP_CONSOLE}
string[] simpsons = {"Homer", "Marge", "Bart", "Lisa", "Maggie"};
Console.WriteLine("Hello! What is your favorite character in the Simpsons (you may only choose from the core family members): ");
string simpson = Console.ReadLine();
int position = Array.IndexOf(simpsons, simpson);
if (position >= 0)
Console.WriteLine("If I had to rank them, that would be no. {0} on my list.", position + 1);
else
Console.WriteLine("Hey! That's not a Simpson!");
Console.ReadKey();
{/CSHARP_CONSOLE}

Console application
Hello! What is your favorite character in the Simpsons (you may only choose from the core family members):
Homer
If I had to rank them, that would be no. 1 on my list!

Copy()

Copy(), as the name suggests, copies a part of the array into another array.
The first parameter is the source array, the second is a target one and the
third is a number of items to be copied.

Methods on the array

The Array class is not the only way to manipulate with arrays. We can also
call a lot of methods directly on individual array instances (concrete
variables). We'll go over a couple of them, but keep in mind that there are
a whole lot of them. We won't make examples this time around,
we'll just describe them:

Length

We've already mentioned Length. It returns the length of an array. It is not
a method, but the property, so we don't write the parentheses () after it.

Min(), Max(), Average(), Sum()

Mathematical methods which return the lesser of the items (Min()), the
largest item (Max()), the average of all the items (Average()) and the sum of
all the items (Sum()). The methods have no parameters.

Concat(), Intersect(), Union()

All these methods return a new array as the output and accept the second
array as the input. Concat() performs a concatenation which merges our array
with the second one and returns a newly created array. Intersect() performs the
intersection of the two arrays. It creates an array with elements that are
common in both arrays. Union(), on the other hand, performs a union. It works
like Concat(), but the elements which were in both arrays are in the new array
will appear only once.

First() and Last()

As the names suggest, these methods return the first and the last item. They
don't take any parameters.

Take() and Skip()

Both of these methods take as a parameter the number of items. Take() returns
an array with a given number of items copied from the beginning of the original
array. Skip(), on the contrary, returns an array without these first items.

Contains()

The method returns true/false depending on whether the item specified as a
parameter is contained in the array.

Reverse()

We already know the Reverse() method from the Array class, but if we call it
on a particular array, the items will be reversed. Instead, a new reversed array
will be created and returned. The method has no parameters.

Distinct()

Distinct() is a method without parameters and ensures that each element will
be in the array only once, thus it removes duplicate elements, and returns a
unique array as the return value. It doesn't modify our original array. Many
methods don't change our arrays directly, but only return a new array, i.e.
Concat(), Intersect(), Union(), Reverse() and Distinct() methods, in which the
desired changes are made. If we want to modify the original array, we have to
assign the returned array to the original one. Unfortunately, these methods
don't return an array directly for a reason which we'll go over later, namely,
the IEnumerable type. If we want to store the result back into the original
array, we have to convert it to an array using the ToArray() method.

This example could obviously be written without an array, but what if we
wanted to compute the median, or print the given numbers backward? We wouldn't
be able to do so without arrays. All of the original values are available in the
array, which we can work with to do whatever we need to.

Download

The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.

The author learned IT at the Unicorn College - a prestigious college providing education on IT and economics.