Hi lovely readers,
If you ever worked with data in the back-end you probably used lists or other collection types before. Getting the data or elements you need from those collections can sometimes be a difficult task, especially if the collection is very big.
C# has a set of extensions that help you write queries. These queries make it easier to filter, select or group the data you need. This set of extensions is collectively called LINQ (Language Integrated Query). Learning how to work with LINQ can be difficult but once you’re good at it, working with data in lists becomes way and way easier.
Lets talk about some examples that are great for beginners that can really help you.
Query syntax or Method syntax
Before we start you have to know that there are two different ways to write LINQ syntax. What you want to use it’s up to you.
There’s query syntax that looks similar to SQL queries, and there is method syntax that’s similar to how you write lambda queries in other backend languages. Let me show you.
Query syntax
//QUERY SYNTAX
//making a new list
List<string> animalNameList = new(){"Boy", "Goku", "Donut", "Cody", "Tebby"};
//filter list
var longAnimalNames = from name in animalNameList
where name.Length >= 5
select name;
This syntax returns all the names that have more than, or are equal to 5 letters. If you already know some SQL, you can tell that is similar to what you’re used there.
The biggest advantage of using Query syntax is that a lot of people find it very readable, and easier to remember. The biggest disadvantage is that LINQ doesn’t allow every method to be used in query syntax. It will sometimes force you to use method syntax instead.
Method syntax
//METHOD SYNTAX
//making a new list
List<string> animalNameList = new(){"Boy", "Goku", "Donut", "Cody", "Tebby"};
//filter list
var longAnimalNames = animalNameList.Where(name => name.Length >= 5);
This syntax, just like the query syntax example, returns all the names that have more than, or are equal to 5 letters. This syntax might be easier if you’re already used to writing lambda queries with Python, Java, or any other backend language.
The advantages are that method syntax looks more like normal C# code. And, you can use every single method available to LINQ. The disadvantage is that, to some, it might be harder to read than query syntax.
Single element methods
These are queries with which you can get one single element out of a list. Keep in mind that if the LINQ query can’t find a element, it will throw an exception. Be sure there is an element that fits the query or use a try - catch block if you’re going to use this in your own code.
ElementAt() method
The ElementAt() method returns the element that’s sitting at the int value you give in the parameter. Here’s an example:
List<string> animalNameList = new(){"Boy", "Goku", "Donut", "Cody", "Tebby"};
var animalName = animalNameList.ElementAt(2);
Console.WriteLine(animalName); //prints 'Donut'
Keep in mind that collections always start at 0, so if you put ElementAt(2) it will return Donut.
First() method
The first() method returns the element that’s at the very beginning of the list. Here’s an example:
List<string> animalNameList = new(){"Boy", "Goku", "Donut", "Cody", "Tebby"};
var animalName = animalNameList.First();
Console.WriteLine(animalName); //prints 'Boy'
Last() method
The last() method returns the element at the very end of the list. Here’s an example:
List<string> animalNameList = new(){"Boy", "Goku", "Donut", "Cody", "Tebby"};
var animalName = animalNameList.Last();
Console.WriteLine(animalName); //prints 'Tebby'
Multiple elements methods
If you want a group of elements instead of just one element, there are methods for that too.
Where() method
The Where() method is used a lot of times and is used for filtering for all kinds of values you need. This can be filtering with conditions or filtering on exact values.
Contains() method
List<string> animalNameList = new(){"Boy", "Goku", "Donut", "Cody", "Tebby"};
var animalNames = animalNameList.Where(name => name.ToLower().Contains('d'));
foreach (string name in animalNames)
{
Console.WriteLine(name); //prints 'Donut' and 'Cody'
}
All the strings that contain the letter d in the list will be stored in the animalNames collection. First, we change every string to only have lowercase letters, and then we look for the letter.
We can also do this in query syntax:
List<string> animalNameList = new(){"Boy", "Goku", "Donut", "Cody", "Tebby"};
var animalNames = from name in animalNameList
where name.ToLower().Contains('d')
select name;
foreach (string name in animalNames)
{
Console.WriteLine(name); //prints 'Donut' and 'Cody'
}
Conditional filtering
You can also filter based on a value that should be true. For example, every name that’s equal to or longer than 5 letters:
List<string> animalNameList = new(){"Boy", "Goku", "Donut", "Cody", "Tebby"};
var longAnimalNames = animalNameList.Where(name => name.Length >= 5);
foreach (string name in longAnimalNames)
{
Console.WriteLine(name); //prints 'Donut' and 'Tebby'
}
And, once again, it works in query syntax as well if that’s what you prefer:
List<string> animalNameList = new(){"Boy", "Goku", "Donut", "Cody", "Tebby"};
var longAnimalNames = from name in animalNameList
where name.Length >= 5
select name;
foreach (string name in longAnimalNames)
{
Console.WriteLine(name); //prints 'Donut' and 'Tebby'
}
Filtering with numeric lists
Can you also filter integer- or double-value lists? Yes, you can. It works the exact same as string lists. Here are some code snippet examples, once again:
List<int> numberList = new() {1, 2, 3, 3, 4, 5, 3, 2, 3, 4};
var numberResult = numberList.Where(number => number is 4 or 2);
foreach (int number in numberResult)
{
Console.WriteLine(number); //prints 2,4,2,4
}
In this query we look through the numberList and store the elements that are either 4 or 2 in the numberResult collection.
and also conditional filtering is an option:
List<int> numberList = new() {1, 2, 3, 3, 4, 5, 3, 2, 3, 4};
var numberResult = numberList.Where(number => number > 3);
foreach (int number in numberResult)
{
Console.WriteLine(number); //prints 4,5,4
}
In this query we put all the elements of integers that are higher than 3 in the collection numberResult.
And of course, we can use both of these examples in query syntax as well!
List<int> numberList = new() {1, 2, 3, 3, 4, 5, 3, 2, 3, 4};
var numberResult = from number in numberList
where number is 4 or 2
select number;
foreach (int number in numberResult)
{
Console.WriteLine(number); //prints 2,4,2,4
}
List<int> numberList = new() {1, 2, 3, 3, 4, 5, 3, 2, 3, 4};
var numberResult = from number in numberList
where number > 3
select number;
foreach (int number in numberResult)
{
Console.WriteLine(number); //prints 4,5,4
}
OrderBy() and OrderByDescending()
Having collections with 2,4,2,4 in it can be quite unhelpful. Sometimes you want to order it and that’s possible. Here’s an example:
List<int> numberList = new(){1, 3, 5, 3, 4, 2};
var numberResult = numberList.OrderBy(number => number);
foreach (int number in numberResult)
{
Console.WriteLine(number); //prints 1,2,3,3,4,5
}
This query puts the numberList in order from lowest value to highest. If you want to it from highest to lowest value you can use OrderByDescending() instead:
List<int> numberList = new(){1, 3, 5, 3, 4, 2};
var numberResult = numberList.OrderByDescending(number => number);
foreach (int number in numberResult)
{
Console.WriteLine(number); //prints 5,4,3,3,2,1
}
You can order the list with query syntax:
List<int> numberList = new(){1, 3, 5, 3, 4, 2};
var numberResult = from number in numberList
orderby number
select number;
foreach (int number in numberResult)
{
Console.WriteLine(number); //prints 1,2,3,3,4,5
}
Where() and OrderBy() method
If you need to, you can use the Where() and OrderBy() together to get even better results. Look at this example:
List<int> numberList = new(){1, 3, 5, 3, 4, 2};
var numberResult = numberList.OrderBy(number => number).Where(number => number > 2);
foreach (int number in numberResult)
{
Console.WriteLine(number); //prints 1,2,3,3,4,5
}
And, of course, in query syntax:
List<int> numberList = new(){1, 3, 5, 3, 4, 2};
var numberResult = from number in numberList
where number > 2
orderby number
select number;
foreach (int number in numberResult)
{
Console.WriteLine(number); //prints 3,3,4,5
}
Boolean methods
Sometimes it can be useful to just know if a list contains something or not, that’s it. So there are methods that give you back a true or false.
Any() method
You can use the Any() method to figure out if there is any element that fits your query. If there is an element (or multiple elements) it will return true:
List<int> numberList = new() {1, 3, 5, 3, 4, 2};
var numberResult = numberList.Any(number => number >= 4);
Console.WriteLine(numberResult);//prints true
Because there’s a 4 and a 5 in the list, the result will be true.
All() method
You can use the All() method to figure out if all elements in the list fits your query. If all the elements fit the query, it will return true:
List<int> numberList = new() {1, 3, 5, 3, 4, 2};
var numberResult = numberList.All(number => number > 0);
Console.WriteLine(numberResult);//prints true
Numeric methods
There are some methods that I don’t exactly know where to put but are still helpful. Here they are
Sum() method
The Sum() method sums up all the values in a numeric list.
List<int> numberList = new() {1, 3, 5, 3, 4, 2};
var numberResult = numberList.All(number => number > 0);
Console.WriteLine(numberResult);//prints 18
Count() method
The Count() method counts up all the elements
List<int> numberList = new() {1, 3, 5, 3, 4, 2};
var numberResult = numberList.Count();
Console.WriteLine(numberResult);//prints 6
Min() method
The Min() method returns the lowest value in a list.
List<int> numberList = new() {1, 3, 5, 3, 4, 2};
var numberResult = numberList.Min();
Console.WriteLine(numberResult);//prints 1
Max() method
The Max() method returns the highest value in a list.
List<int> numberList = new() {1, 3, 5, 3, 4, 2};
var numberResult = numberList.Max();
Console.WriteLine(numberResult);//prints 5
That’s a wrap!
Thank you for reading. I hope this can help you in your (future) career as a .NET or C# developer. If you have any suggestions or tips, feel free to leave a comment or contact me on Twitter at @lovelacecoding. See you later!