When programming, one of the most commonly used features is data collections, whether they come from a database, an external service, or data we create ourselves. For example, imagine we have a list of employees or students in a school.
In this tutorial, we'll see how to work with this type of data. We don’t create a variable for each employee or student; instead, we create a data structure called a collection. These collections can be arrays or Lists.
Table of Contents
1 - What is an Array?
An array is a type that allows us to store a collection of data of a desired type. These types can be either primitive or custom types created by us.
Another feature of arrays is that they have no size limit and can contain as many records as we want, as long as there is enough memory in the computer. But the important thing is that the compiler will not impose a limit on us.
Finally, arrays are immutable, which means that once we initialize them, they do not change. For example, we cannot add or remove elements from an array.
1.1 - Declaring an Array
To declare an array, we first indicate the data type, as mentioned, either primitive or custom. Followed by a pair of brackets [] indicating that it is an array, and when declared, we specify the size that the array will have.
int[] arrayEnteros = new int[5];This is the graphical representation of the code:
1.2 - Assigning values to the elements of an array
Once we have our array initialized, it is created “empty” and what we need to do is assign it values. To do so, we access the position in the array via the index, which in programming, we remember that indices start at position 0. And the last element will be placed at the position before the size of the array, in this case 4 (n-1 = last position).
arrayEnteros[0] = 25;
arrayEnteros[1] = 27;
arrayEnteros[2] = 25;
arrayEnteros[3] = 29;
arrayEnteros[4] = 20;In this way, we assign values to the elements of the array, as we see, accessing by position. This would be the representation for each line of code:
As we saw in the video about variables and operators, in this case, we can also initialize arrays when we declare them, like this:
int[] arrayEnteros = { 25, 27, 25, 29, 20 }This generates exactly the same result as the previous example. But as we notice, we don't specify the size explicitly, but it is inferred from the number of parameters we provide.
1.3 - Working with the array
As we mentioned earlier, arrays are immutable, which means we cannot modify them, but we can still work with them.
Normally when we have a collection, whether lists or arrays, we tend to work with the data both as a whole and individually. To work with them individually, what we need to do is access each element of the array individually through the index.
Commonly, we access records one by one using a for loop in the following way:
for(int i = 0; i < arrayEnteros.Length; i++){
   Console.WriteLine($"El numero es: {arrayEnteros[i]}")
}As we see in the loop, to indicate the second parameter and know how many iterations to execute, we used a function that comes with Array: Array.Length.
Just like Array.Length, the type itself comes with a wide variety of methods we can use if we need them.
- Array.Contains(element)Will return- Trueor- Falseif the element is within the array.
- Array.Reverse()Will return the array in reverse order.
There are many more methods that we'll see later as we work with them.
2 - Multidimensional array
A regular array will not always meet all our needs; for some scenarios, we’ll need an array with n dimensions. For this, we have multidimensional arrays.
2.1 - Declaring a multidimensional array
Very similar to before, but in this case, instead of creating a single list, it will create a sort of table. Like before, for multidimensional arrays, we also need to specify the number of elements it will contain.
string[,] ciudades = new string[2, 3];The graphical result would be something like this:
2.2 - Assigning values to the elements of a multidimensional array
To access the elements of a multidimensional array, we do exactly as we do with a normal array. The only difference is that in this case, we need two indices.
ciudades[0, 0] = "Teruel";
ciudades[0, 1] = "Huesca";
ciudades[0, 2] = "Zaragoza";
ciudades[1, 0] = "Valencia";
ciudades[1, 1] = "castellon";
ciudades[1, 2] = "Alicante";
And the final result of inserting the data into this multidimensional array:
2.3 - Working with a multidimensional array
Because we need to access with two indices, the way we loop through the array is different. In this case, we will need a for loop inside another for loop, and then access with both indices ciudades[i, j].
for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 3; j++)
    {
        Console.WriteLine($"La ciudad es {ciudades[i,j]}");
    }
}
3 - Jagged array
As mentioned in the previous case, many times we need an array with several dimensions, but we don’t need to have the same number of dimensions for all the elements of the array.
To give a simple example, imagine we want to read from a database all the salary changes of two employees. For this, we would use a multidimensional array: the first row for the first employee, the second row for the second.
For this example, employee1 has changed salary twice since working, whereas employee2 has changed salary seven times.
With a multidimensional array, we would have to create an array like decimal[,] arraySueldos = new decimal[2, 7]. This example, taken to a list of 10,000 or 10 million records, can cause terrible performance and memory problems, since for the first employee, we are reserving 4 memory spaces that we will never use. To avoid this problem, we have jagged arrays.
3.1 - Declaring a jagged array
Jagged arrays are defined in a slightly different way, since what we do is mix the two previously seen, array and multidimensional array.
string[][] provincias= new string[3][];This way we create space for 3 arrays, each independent, which we have to assign a size. Like this:
provincias[0] = new string[3];
provincias[1] = new string[2]; 
provincias[2] = new string[4];As we see, we access each array element by index and instantiate a new array inside it. This new array will indicate its size.
The graphical representation is as follows:
As you can see, there are “blank” spaces, which means that space in memory is not used.
3.2 - Assigning values to the elements of a jagged array
To assign values, we need to do the same process, which is to access by index; the difference is that, in this case, the indices are not fixed, so when reading, we will do it differently. To assign values, we do it directly since we know (or should) the size.
provincias[0][0] = "Huesca";
provincias[0][1] = "Zaragoza";
provincias[0][2] = "Teruel";
provincias[1][0] = "Cáceres";
provincias[1][1] = "Badajoz";
provincias[2][0] = "A Coruña";
provincias[2][1] = "Pontevedra";
provincias[2][2] = "Ourense";
provincias[2][3] = "Lugo";
And the representation would be as follows:
3.3 - Working with a jagged array
In this case, the array is totally dynamic: each record has a different size, so to iterate over it, we must check the size of each record, as we saw earlier with .Length.
for (int i = 0; i < provincias.Length; i++)
{
   System.Console.Write($"registro ({i}): ", i);
   for (int j = 0; j < provincias[i].Length; j++)
   {
         System.Console.Write("{0}{1}", provincias[i][j], j == (provincias[i].Length - 1) ? "" : " ");
   }
   System.Console.WriteLine();            
}
//Result
registro (1):
Hueca Zaragoza Teruel
registro (2):
Cáceres Badajoz
registro (3):
A coruña Pontevedra, ourense Lugo
As a final note: you can mix multidimensional arrays with jagged arrays, but to be honest, I don't recommend it. There are better ways to arrive at a solution, not to mention that it is seldom seen in the workplace.
4 - Lists or List<T>
Now we leave arrays behind to move to one of the most used elements in the C# environment: lists or List<T>. This data type is used frequently thanks to its ease and great functionality.
List<T> is a data type, similar to the array type we just saw, but in this case, they are mutable, meaning we can add or remove elements whenever we want.
Another very important thing to keep in mind about lists is that they implement IEnumerable<T>, an interface that allows you to execute LINQ queries, which we will see in this post. Because of this, the use of lists is constant in our applications.
4.1 - Creating a list
When we create a list, unlike arrays, we don't use an index, as these, being mutable, don't have a predefined size from initialization. To replicate the previous example, to create a list of strings, we do the following:
List<string> provincias = new List<string>();As we can see, the T in List<T> is the data type we want to use, which can be primitive or not.
4.2 - Adding elements to a list
As indicated earlier, we no longer access by index, so to add elements, we do it in a more dynamic way with the .Add(T) method, where we must pass as a parameter a data type of what the list is, in this case, string.
provincias.Add("Teruel");In addition to this, if we have a list and want to add it into another list (for example, listing all provinces grouped by regions), we can add a list into another using .AddRange(List<T>)
aragon.Add("Huesca");
aragon.Add("Zaragoza");
aragon.Add("Teruel");
provincias.AddRange(aragon);As we see in the example, we pass the "aragon" list as a parameter.
4.3 - Working with a list
In this case, to work with a list, we can use any of the vast number of methods the compiler provides. Here, we'll see just a few as examples.
First, let's see how to iterate a list. We'll use a foreach loop:
foreach (string provincia in provincias){
   Console.WriteLine($"la provincia es {provincia}");
}More methods we can use:
- lista.ToArray(); converts the list to an array.
- lista.Count; returns an integer with the number of elements in the list.
- lista.First(); returns the first element.
- lista.Last(); returns the last element.
- lista.Clear(); empties or removes all elements from the list.
5 - LINQ
First, let’s note that what we’re going to see is a small introduction to the LINQ language, as covering everything would take dozens of videos.
5.1 - What is LINQ
LINQ is a database query language, or at least that was its original intention. While LINQ was being developed, they realized that a List<T> is nothing more than the results we get from querying a DB, so why not take advantage and use it in our code, not only to query but also to filter.
5.2 - How to use LINQ
Using LINQ in our code is easy: we just need to use a type that extends the IEnumerable<T> class, such as List<T>.
To use it, indicate: list.Where(condition)
Inside "condition" we need to indicate the element we’re iterating over; commonly I use the letter a, but many people use the initial of the element, in this case (for example, provincias) p.
In our example provincias.Where(p => p) with p=>p we indicate where to run the query, which at the same time, iterates individually over each element in the list.
To add conditions to the query, we can use the same conditions available in their types. In this example, for the string type, we’ll use the .Contains() method, which returns true or false if the element to check contains the value passed as a parameter.
Next, we loop over the result, printing each record.
provincias.Add("Huesca");
provincias.Add("Zaragoza");
provincias.Add("Teruel");
IEnumerable<string> provinciasFiltradas = provincias.Where(p => p.Contains("e"));
foreach(string provincia in provinciasFiltradas){
   Console.WriteLine(provincia);
}
In this scenario, it prints both Huesca and Teruel, since both contain the letter e (lowercase).
If there is any problem you can add a comment bellow or contact me in the website's contact form
 
                    