Loops and Collections

Loops & Collections

Loops:

Loops in C# are control structures that allow repeating a block of code multiple times. Loops are fundamental for controlling execution flow in a program. Here's a description of the most common types of loops in C# along with examples:

While loop:

  • The while loop executes as long as a condition is true. It's important to ensure that the condition changes at some point to avoid an infinite loop.

int counter = 0;
while (counter < 5)
{
    Console.WriteLine("Iteration " + counter);
    counter++;
}

Do-while loop:

  • The do-while loop is similar to while, but guarantees that the code block executes at least once before checking the condition.

int number = 5;
do
{
    Console.WriteLine("Number equals " + number);
    number--;
} while (number > 0);

For loop:

  • The for loop is useful when you know in advance the number of iterations needed. It includes an initialization, a condition, and an increment expression.

for (int i = 0; i < 5; i++)
{
    Console.WriteLine("Iteration " + i);
}

💡 Besides doing it incrementally, you can also do it decrementally!


Foreach loop:

  • The foreach loop is mainly used to iterate through elements of a collection, such as arrays or lists. (In a minute you'll know what a list or array is)

string[] names = { "John", "Maria", "Peter" };
foreach (string name in names)
{
    Console.WriteLine(name);
}

Break and continue loops:

  • You can use the break statement to exit a loop before the condition is met and continue to skip the current iteration and move to the next one.

for (int i = 0; i < 10; i++)
{
    if (i == 5)
        break; // Exit the loop when i equals 5
    if (i % 2 == 0)
        continue; // Skip even iterations
    Console.WriteLine("Odd number: " + i);
}

Collections:

Collections in C# are data structures that allow storing and manipulating sets of elements. Here's a description of the most common types of collections in C# along with examples:

Array[]

  • An array is a collection of elements of the same type with a fixed size that is declared at compile time.

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

Array declaration:

  • To declare an array, you can use the following syntax:

type[] arrayName = new type[size];
int[] numbers = new int[5]; // Declare an integer array with size 5

Array initialization:

  • You can initialize an array with values at the moment of declaration:

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

Element access:

  • To access array elements, you can use the index in brackets:

numbers[2] = 10; // Overwrite the third element with the value 10

Array length:

  • You can get the length of an array using the Length property:

int length = numbers.Length;

Clone an array:

  • You can create a copy of an array using the Clone() method:

int[] copyNumbers = (int[])numbers.Clone();

Sort an array:

  • You can sort an array using the Array.Sort() method:

Array.Sort(numbers); // Sort the array in ascending order

Search for an element in an array:

  • You can search for an element in an array using the Array.IndexOf() method:

int index = Array.IndexOf(numbers, 3); // Search for the index of value 3

Traverse an array:

  • You can traverse an array using loops like for or foreach (as we saw in the previous section).

Keep in mind that if you need to add or remove elements from a collection dynamically, you might want to consider using other data structures like List<T> instead of arrays, since lists allow more flexible operations for inserting and removing elements.


List<>

  • A list is a dynamic collection that can grow or shrink in size as needed.

List<int> numbers = new List<int>();

Add elements to a list:

  • You can add elements to a list using the Add() method:

List<string> names = new List<string>();
names.Add("John");
names.Add("Maria");
names.Add("Peter");

Access list elements:

  • To access list elements, you can use the index in brackets, just like with arrays:

int firstNumber = numbers[0];
int secondNumber = numbers[1];

Overwrite list elements:

  • You can overwrite an existing element in a list using the index:

numbers[2] = 10;

Get the length of a list:

  • You can get the number of elements in a list using the Count property: (Be careful, it's not like arrays where Length is used)

int firstNumber = numbers[0];
int secondNumber = numbers[1];
int thirdNumber = numbers[2];
int length = numbers.Count; // Get the list length (in this case, 3) Although the maximum index is 2

Clone a list:

  • You can create a copy of a list using the List<T> constructor that takes another list as an argument:

List<int> copyNumbers = new List<int>(numbers);

Sort a list:

  • You can sort a list using the Sort() method:

numbers.Sort(); // Sort the list in ascending order

Search for an element in a list:

  • You can search for an element in a list using the IndexOf() method:

int index = numbers.IndexOf(3); // Search for the index of value 3

Remove elements from a list:

  • You can remove elements from a list using methods like Remove(), RemoveAt(), or RemoveAll():

numbers.Remove(2); // Remove the value 2 from the list
numbers.RemoveAt(0); // Remove the first element from the list
numbers.RemoveAll(x => x > 5); // Remove all elements greater than 5

Traverse a list:

  • You can traverse a list using loops like for or foreach just like with arrays.


Dictionary

Dictionaries in C# are a data structure that stores key-value pairs, where each key is unique. Here's a description of the most common operations you can perform with a Dictionary<TKey, TValue> in C#, along with examples:

Dictionary declaration and initialization:

  • You can declare and initialize a dictionary as follows:

Dictionary<string, int> ages = new Dictionary<string, int>();

Add elements to a dictionary:

  • You can add key-value pairs to a dictionary using the Add() method:

ages.Add("John", 30);
ages.Add("Maria", 25);
ages.Add("Peter", 28);

Access dictionary values:

  • To access dictionary values, you can use the key as an index:

int johnAge = ages["John"];

Keep in mind that if the key doesn't exist in the dictionary, this will throw a KeyNotFoundException. To avoid this, you can use the TryGetValue() method:

int johnAge;
if (ages.TryGetValue("John", out johnAge))
{
    // The key exists and the value has been obtained
}

Check if a key exists in a dictionary:

  • You can check if a key exists in a dictionary using the ContainsKey() method:

if (ages.ContainsKey("Maria"))
{
    // The key "Maria" exists in the dictionary
}

Remove elements from a dictionary:

  • You can remove elements from a dictionary using the Remove() method:

ages.Remove("Peter"); // Remove the entry with key "Peter"

Clear a dictionary:

  • You can remove all elements from a dictionary using the Clear() method:

ages.Clear(); // Remove all elements from the dictionary

Get the number of elements in a dictionary:

  • You can get the number of elements in a dictionary using the Count property:

int numberOfElements = ages.Count;

Traverse a dictionary:

  • You can traverse a dictionary using a foreach loop or access its keys or values using the Keys and Values properties. Same as with arrays and Lists but keeping in mind that you handle 2 values.

foreach (var kvp in ages)
{
    Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
}

foreach (string name in ages.Keys)
{
    Console.WriteLine("Name: " + name);
}

foreach (int age in ages.Values)
{
    Console.WriteLine("Age: " + age);
}

Dictionaries (Dictionary<TKey, TValue>) are ideal when you need to associate values with unique keys and perform efficient searches. They are a fundamental data structure in programming and are widely used in many applications.


Other collections:

While the most common is to use Array, List and Dictionary. There are other types of very useful collections that have other uses. I'm not going to go deep into them now because it would be too much data all at once. But it is important that you read them to know they exist and if you ever have to do something similar you can google how to use them and what they do.

Tuple:

  • A tuple is an ordered collection of elements of different types. It's used when you need a simple data structure to store related values. Unlike Dictionary, the tuple can store 2 or more equal keys. Because they're not keys.

Tuple<string, int, bool> person = new Tuple<string, int, bool>("John", 30, true);

HashSet:

  • A set (HashSet) is a collection that stores unique elements without duplicates. It's useful when you need to guarantee that there are no repeated elements. It's the opposite of a Dictionary where instead of not being able to have 2 equal keys. You can't have 2 equal values.

HashSet<int> uniqueNumbers = new HashSet<int>();
uniqueNumbers.Add(1);
uniqueNumbers.Add(2);
uniqueNumbers.Add(1); // Won't be added, since 1 is duplicated

Stack:

  • A stack is a collection that follows the LIFO principle (last in, first out). It's used to store elements that must be processed in reverse order. It can be used perfectly in a deck of cards. Because the first one you add will be the last one to come out.

Stack<string> cards = new Stack<string>();
cards.Push("AceOfSpades");
cards.Push("AceOfClubs");
string lastCard = cards.Pop(); // Returns "AceOfClubs"

Queue:

  • A queue is a collection that follows the FIFO principle (first in, first out). It's used to store elements that must be processed in the order they were added, similar to a line in real life. (The opposite of Stack)

Queue<string> clientQueue = new Queue<string>();
clientQueue.Enqueue("Client1");
clientQueue.Enqueue("Client2");
string nextClient = clientQueue.Dequeue(); // Returns "Client1"

In the example, clients are added to the queue in order. When Dequeue() is called, the first client who arrived at the queue is removed and returned, which in this case is "Client1". This ensures that elements are handled in the same order they were added, which is useful in situations where it's important to maintain a specific order, such as task or process management in a system.


Last updated