LINQ basics: Where, Select, OrderBy
Query collections like a database: filter, sort, transform, take and summarise data in a few readable lines.
ifs and temporary lists, you describe what you want and LINQ does the looping.
Loop vs LINQ
// With a loopvar marks1 = new List<string>();foreach (var b in beams) if (b.Length > 6) marks1.Add(b.Mark);marks1.Sort(); // With LINQ: same result, and it reads like the requirementvar marks2 = beams .Where(b => b.Length > 6) .Select(b => b.Mark) .OrderBy(m => m) .ToList();The core operators
| Operator | Does | Example |
|---|---|---|
Where | .Where(b => b.Level == 2) | |
Select | .Select(b => b.Mark) | |
OrderBy / OrderByDescending | .OrderByDescending(b => b.Kg) | |
ThenBy | .OrderBy(b => b.Level).ThenBy(b => b.Mark) | |
Take / Skip | .Skip(20).Take(10) | |
Distinct | .Select(b => b.Profile).Distinct() | |
ToList / ToArray | .ToList() |
Single results and checks
Beam? first = beams.FirstOrDefault(b => b.Profile == "HEA200"); // null if nonebool anyHeavy = beams.Any(b => b.Kg > 300);bool allValid = beams.All(b => b.Length > 0);int count = beams.Count(b => b.Level == 1); double totalKg = beams.Sum(b => b.Kg);double avgLen = beams.Average(b => b.Length);double longest = beams.Max(b => b.Length);Beam heaviest = beams.MaxBy(b => b.Kg)!; // .NET 6+ Console.WriteLine($"{count} on level 1, {totalKg} kg total, heaviest {heaviest.Mark}"); Output
3 on level 1, 1773 kg total, heaviest B4
Anonymous types in Select
var report = beams .Where(b => b.Level == 2) .Select(b => new { b.Mark, Tonnes = b.Kg / 1000.0 }); // a type made on the fly foreach (var r in report) Console.WriteLine($"{r.Mark}: {r.Tonnes:F3} t"); Output
B4: 0.338 t B5: 0.067 t B6: 0.233 t
Query syntax
var q = from b in beams where b.Length > 6 orderby b.Kg descending select b.Mark; Practice
int[] scores = { 72, 45, 90, 61, 88, 39, 77 };, use LINQ to print: the passing scores (≥ 50) sorted highest first, how many failed, and the average of the passing scores to 1 decimal.
Show the solution
int[] scores = { 72, 45, 90, 61, 88, 39, 77 }; var passed = scores.Where(s => s >= 50).OrderByDescending(s => s).ToList();int failed = scores.Count(s => s < 50); Console.WriteLine(string.Join(", ", passed));Console.WriteLine($"Failed: {failed}");Console.WriteLine($"Average pass: {passed.Average():F1}"); Output
90, 88, 77, 72, 61 Failed: 2 Average pass: 77.6
Remember
LINQ queries collections with Where,Select,OrderBy,Take…Chain operators; finish with ToList()to get a stored result.Use Any,Count,Sum,Average,Max,MaxByfor answers.Prefer FirstOrDefaultwhen nothing may match.