PYnative

Python Programming

  • Learn Python ▼
    • Python Tutorials
    • Python Basics
    • Python Interview Q&As
  • Exercises ▼
    • Python Exercises
    • C++ Exercises
    • C Programming Exercises
    • Java Exercises
    • C# Exercises
  • Quizzes
  • Code Editor ▼
    • Online Python Code Editor
    • Online C Compiler
    • Online C++ Compiler
    • Online Java Compiler
    • Online C# Compiler
Home » C# Exercises » C# LINQ Exercises: 40 Coding Problems with Solutions

C# LINQ Exercises: 40 Coding Problems with Solutions

Updated on: July 15, 2026 | Leave a Comment

LINQ (Language-Integrated Query) is one of C#’s most powerful features, letting you filter, transform, sort, and aggregate data with clean, expressive syntax instead of writing manual loops.

This collection of 40 C# LINQ exercises takes you through the most commonly used methods, Where(), Select(), OrderBy(), GroupBy(), and aggregation functions, so you can start writing more concise, readable C# code.

Each exercise includes a Practice Problem, Purpose, Hint, and a full Solution with Explanation, so you understand exactly how each LINQ method transforms your data.

Also, See: C# Exercises with  22 topic-wise sets and 620+ practice questions.

What You’ll Practice

  • Filtering & Projection: .Where() and .Select().
  • Sorting & Grouping: .OrderBy(), .OrderByDescending(), and .GroupBy().
  • Aggregation: .Sum(), .Average(), .Min(), .Max(), and .Count().
  • Element Operations: .FirstOrDefault(), .Any(), and method chaining.
+ Table Of Contents (40 Exercises)

Table of contents

  • Exercise 1: Filtering Even Numbers
  • Exercise 2: Finding Long Words
  • Exercise 3: Sorting Names in Reverse
  • Exercise 4: Finding the Top 3 Unique Numbers
  • Exercise 5: Paginating a Product List
  • Exercise 6: Finding Fruits Starting with A
  • Exercise 7: Filtering Ages in a Range
  • Exercise 8: Squaring a List of Numbers
  • Exercise 9: Finding the First Match
  • Exercise 10: Finding the Last Match
  • Exercise 11: Converting Strings to Uppercase
  • Exercise 12: Projecting Object Properties
  • Exercise 13: Creating Anonymous Types
  • Exercise 14: Flattening Nested Lists
  • Exercise 15: Finding Unique Characters
  • Exercise 16: Projecting with Index
  • Exercise 17: Zipping Two Arrays Together
  • Exercise 18: Extracting Unique Email Domains
  • Exercise 19: Flattening a 2D Array
  • Exercise 20: Extracting File Extensions
  • Exercise 21: Summing Squares of Odd Numbers
  • Exercise 22: Averaging Prices with a Condition
  • Exercise 23: Finding Min and Max Price
  • Exercise 24: Counting Matching Elements
  • Exercise 25: Joining Words with Aggregate
  • Exercise 26: Calculating Factorial with LINQ
  • Exercise 27: Summing Department Salaries
  • Exercise 28: Counting Vowels with LINQ
  • Exercise 29: Multiplying Numbers with Aggregate
  • Exercise 30: Finding the Longest Word
  • Exercise 31: Grouping People by Age
  • Exercise 32: Counting Words by Length
  • Exercise 33: Joining Students and Courses
  • Exercise 34: Left Joining Employees and Departments
  • Exercise 35: Finding Common Numbers
  • Exercise 36: Finding Missing Products
  • Exercise 37: Combining Lists Without Duplicates
  • Exercise 38: Finding the Most Frequent Number
  • Exercise 39: Finding the Highest Paid Employee per Department
  • Exercise 40: Splitting a List into Chunks

Exercise 1: Filtering Even Numbers

Practice Problem: Given a list of integers, return only the even numbers.

Purpose: This exercise helps you practice the Where() method, the most fundamental LINQ operator for filtering a sequence down to elements that satisfy a condition.

Given Input: numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }

Expected Output:

Filtering even numbers from the list:
Even Numbers: 2, 4, 6, 8, 10
Filtering completed successfully.
▼ Hint
  • Use the Where() LINQ method with a lambda expression.
  • Check each number using the modulus operator: n % 2 == 0.
  • Call ToList() to convert the result into a list.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqUtilities
{
    class EvenNumberFilter
    {
        static void Main(string[] args)
        {
            List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

            Console.WriteLine("Filtering even numbers from the list:");

            List<int> evenNumbers = numbers.Where(n => n % 2 == 0).ToList();

            Console.WriteLine($"Even Numbers: {string.Join(", ", evenNumbers)}");
            Console.WriteLine("Filtering completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • numbers.Where(n => n % 2 == 0): Uses LINQ’s Where() method to keep only the elements that satisfy the condition, in this case, numbers divisible by 2 with no remainder.
  • n % 2 == 0: The lambda expression checks each number for evenness.
  • .ToList(): Converts the filtered LINQ query into a concrete List<int>.

Exercise 2: Finding Long Words

Practice Problem: Given a list of words, find all words that have more than 5 characters.

Purpose: This exercise helps you practice filtering a sequence of strings based on a property of each element, in this case, its length.

Given Input: words = new List<string> { "cat", "elephant", "dog", "butterfly", "ox", "giraffe" }

Expected Output:

Finding words longer than 5 characters:
Long Words: elephant, butterfly, giraffe
Filtering completed successfully.
▼ Hint
  • Use Where() with a lambda that checks each word’s Length property.
  • The condition should be w.Length > 5.
  • Convert the result to a list with ToList().
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqUtilities
{
    class LongWordFinder
    {
        static void Main(string[] args)
        {
            List<string> words = new List<string> { "cat", "elephant", "dog", "butterfly", "ox", "giraffe" };

            Console.WriteLine("Finding words longer than 5 characters:");

            List<string> longWords = words.Where(w => w.Length > 5).ToList();

            Console.WriteLine($"Long Words: {string.Join(", ", longWords)}");
            Console.WriteLine("Filtering completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • words.Where(w => w.Length > 5): Filters the list to keep only words whose Length property is greater than 5.
  • w.Length: Accesses each string’s character count directly within the lambda.
  • .ToList(): Materializes the filtered results into a List<string>.

Exercise 3: Sorting Names in Reverse

Practice Problem: Given a list of names, sort them in descending alphabetical order.

Purpose: This exercise helps you practice the OrderByDescending() method for sorting a sequence in reverse order using the elements’ natural comparison.

Given Input: names = new List<string> { "Charlie", "Alice", "Bob", "Eve", "Dave" }

Expected Output:

Sorting names in descending alphabetical order:
Sorted Names: Eve, Dave, Charlie, Bob, Alice
Sorting completed successfully.
▼ Hint
  • Use OrderByDescending() instead of OrderBy() to sort in reverse order.
  • Since you’re sorting the strings themselves, the lambda can simply be name => name.
  • Call ToList() to get the final sorted list.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class DescendingNameSorter
    {
        static void Main(string[] args)
        {
            List<string> names = new List<string> { "Charlie", "Alice", "Bob", "Eve", "Dave" };
            Console.WriteLine("Sorting names in descending alphabetical order:");
            List<string> sortedNames = names.OrderByDescending(name => name).ToList();
            Console.WriteLine($"Sorted Names: {string.Join(", ", sortedNames)}");
            Console.WriteLine("Sorting completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • names.OrderByDescending(name => name): Sorts the strings using their natural alphabetical comparison, but in reverse (Z to A) order.
  • The lambda name => name: Tells LINQ to use each string’s own value as the sort key, rather than some derived property.
  • .ToList(): Converts the sorted sequence into a concrete list.

Exercise 4: Finding the Top 3 Unique Numbers

Practice Problem: From an array of integers, select the top 3 highest unique values.

Purpose: This exercise helps you practice chaining multiple LINQ methods together, Distinct(), OrderByDescending(), and Take(), to build a multi-step query.

Given Input: numbers = new int[] { 50, 20, 50, 80, 80, 10, 30, 90 }

Expected Output:

Finding the top 3 highest unique values:
Top 3 Unique Numbers: 90, 80, 50
Search completed successfully.
▼ Hint
  • Use Distinct() first to remove duplicate values.
  • Chain OrderByDescending() to sort the unique values from highest to lowest.
  • Use Take(3) to grab the top three, then convert with ToArray() or ToList().
▼ Solution & Explanation
using System;
using System.Linq;

namespace LinqUtilities
{
    class TopUniqueNumbersFinder
    {
        static void Main(string[] args)
        {
            int[] numbers = { 50, 20, 50, 80, 80, 10, 30, 90 };

            Console.WriteLine("Finding the top 3 highest unique values:");

            int[] topThree = numbers.Distinct().OrderByDescending(n => n).Take(3).ToArray();

            Console.WriteLine($"Top 3 Unique Numbers: {string.Join(", ", topThree)}");
            Console.WriteLine("Search completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • numbers.Distinct(): Removes duplicate values from the array first, so repeated numbers like 50 and 80 only count once.
  • .OrderByDescending(n => n): Sorts the remaining unique values from highest to lowest.
  • .Take(3): Selects only the first three values from the sorted sequence, the three highest unique numbers.
  • .ToArray(): Converts the final LINQ query into a concrete array.

Exercise 5: Paginating a Product List

Practice Problem: Given a list of 100 products, skip the first 20 and take the next 10.

Purpose: This exercise helps you practice the Skip-then-Take pattern, the standard way to extract a single page of results from a larger sequence.

Given Input: A list of 100 products named “Product 1” through “Product 100”

Expected Output:

Skipping the first 20 products and taking the next 10:
Result: Product 21, Product 22, Product 23, Product 24, Product 25, Product 26, Product 27, Product 28, Product 29, Product 30
Pagination completed successfully.
▼ Hint
  • Use Enumerable.Range() combined with Select() to quickly generate 100 sample products.
  • Chain Skip(20) to skip over the first 20 items.
  • Chain Take(10) after Skip() to grab the next 10 items.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class ProductPaginationDemo
    {
        static void Main(string[] args)
        {
            List<string> products = Enumerable.Range(1, 100).Select(i => $"Product {i}").ToList();
            Console.WriteLine("Skipping the first 20 products and taking the next 10:");
            List<string> pagedProducts = products.Skip(20).Take(10).ToList();
            Console.WriteLine($"Result: {string.Join(", ", pagedProducts)}");
            Console.WriteLine("Pagination completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • Enumerable.Range(1, 100).Select(i => $"Product {i}"): Generates a sequence of 100 product names to simulate a large dataset.
  • products.Skip(20): Skips over the first 20 elements in the list, leaving everything from the 21st item onward.
  • .Take(10): Selects only the next 10 items after the skipped ones.
  • Together: Skip() and Take() extract exactly one page of results from a larger sequence.

Exercise 6: Finding Fruits Starting with A

Practice Problem: Find all fruits in a string array that start with the letter ‘A’ (case-insensitive).

Purpose: This exercise helps you practice combining Where() with StartsWith() and a case-insensitive comparison option, so casing differences don’t affect the match.

Given Input: fruits = new string[] { "apple", "Banana", "Avocado", "cherry", "apricot", "Mango" }

Expected Output:

Finding fruits that start with the letter 'A':
Fruits: apple, Avocado, apricot
Search completed successfully.
▼ Hint
  • Use Where() with a lambda that calls StartsWith("A", ...) on each fruit.
  • Pass StringComparison.OrdinalIgnoreCase as the second argument to make the check case-insensitive.
  • Convert the result to an array or list as needed.
▼ Solution & Explanation
using System;
using System.Linq;

namespace LinqUtilities
{
    class FruitFinder
    {
        static void Main(string[] args)
        {
            string[] fruits = { "apple", "Banana", "Avocado", "cherry", "apricot", "Mango" };

            Console.WriteLine("Finding fruits that start with the letter 'A':");

            string[] aFruits = fruits
                .Where(f => f.StartsWith("A", StringComparison.OrdinalIgnoreCase))
                .ToArray();

            Console.WriteLine($"Fruits: {string.Join(", ", aFruits)}");
            Console.WriteLine("Search completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • fruits.Where(f => f.StartsWith("A", StringComparison.OrdinalIgnoreCase)): Filters the array to keep only strings that begin with “A”, ignoring whether the actual letter is upper or lower case.
  • StringComparison.OrdinalIgnoreCase: Tells StartsWith() to treat “a” and “A” as equivalent during the comparison.
  • Why this matters: Without this comparison option, StartsWith() would be case-sensitive by default and miss lowercase entries like “apple”.

Exercise 7: Filtering Ages in a Range

Practice Problem: Given a list of employee ages, find all employees between the ages of 25 and 35 (inclusive).

Purpose: This exercise helps you practice combining two conditions inside a single Where() lambda using the logical && operator.

Given Input: ages = new List<int> { 22, 25, 30, 35, 40, 28, 19, 33 }

Expected Output:

Finding employees aged between 25 and 35 (inclusive):
Ages: 25, 30, 35, 28, 33
Range filtering completed successfully.
▼ Hint
  • Use Where() with a lambda that checks two conditions combined with &&.
  • The condition should be age >= 25 && age <= 35 to make both boundary values inclusive.
  • Convert the result to a list with ToList().
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class AgeRangeFilter
    {
        static void Main(string[] args)
        {
            List<int> ages = new List<int> { 22, 25, 30, 35, 40, 28, 19, 33 };
            Console.WriteLine("Finding employees aged between 25 and 35 (inclusive):");
            List<int> inRange = ages.Where(age => age >= 25 && age <= 35).ToList();
            Console.WriteLine($"Ages: {string.Join(", ", inRange)}");
            Console.WriteLine("Range filtering completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • ages.Where(age => age >= 25 && age <= 35): Keeps only the ages that fall within the inclusive range, using two comparisons combined with &&.
  • age >= 25 && age <= 35: Both conditions must be true for an age to be included; "inclusive" means the boundary values 25 and 35 themselves qualify.
  • .ToList(): Converts the filtered sequence into a List<int>.

Exercise 8: Squaring a List of Numbers

Practice Problem: Take a list of integers and return a list of their squares.

Purpose: This exercise helps you practice the Select() method, LINQ's projection operator, used to transform each element of a sequence into a new value.

Given Input: numbers = new List<int> { 1, 2, 3, 4, 5 }

Expected Output:

Squaring each number in the list:
Squares: 1, 4, 9, 16, 25
Transformation completed successfully.
▼ Hint
  • Use Select() instead of Where(), since you're transforming values rather than filtering them.
  • The lambda should square each number: n => n * n.
  • Convert the result to a list with ToList().
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class NumberSquarer
    {
        static void Main(string[] args)
        {
            List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
            Console.WriteLine("Squaring each number in the list:");
            List<int> squares = numbers.Select(n => n * n).ToList();
            Console.WriteLine($"Squares: {string.Join(", ", squares)}");
            Console.WriteLine("Transformation completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • numbers.Select(n => n * n): Transforms each element in the list into a new value, in this case, its square, without changing the original list.
  • n * n: The lambda expression squares each number as it passes through the projection.
  • .ToList(): Converts the projected sequence into a new List<int>.

Exercise 9: Finding the First Match

Practice Problem: Find the first number in a list that is divisible by 7. Return a default value if none exist.

Purpose: This exercise helps you practice using FirstOrDefault() instead of First(), so your program doesn't throw an exception when no element matches the condition.

Given Input: numbers = new List<int> { 10, 15, 22, 33, 41, 50 }

Expected Output:

Finding the first number divisible by 7:
Result: 0
Search completed successfully.
▼ Hint
  • Use FirstOrDefault() instead of First(), since a match isn't guaranteed to exist.
  • The condition should check n % 7 == 0.
  • If no element matches, FirstOrDefault() returns the type's default value (0 for int) instead of throwing an exception.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class FirstDivisibleFinder
    {
        static void Main(string[] args)
        {
            List<int> numbers = new List<int> { 10, 15, 22, 33, 41, 50 };
            Console.WriteLine("Finding the first number divisible by 7:");
            int result = numbers.FirstOrDefault(n => n % 7 == 0);
            Console.WriteLine($"Result: {result}");
            Console.WriteLine("Search completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • numbers.FirstOrDefault(n => n % 7 == 0): Searches for the first number in the list matching the condition, and returns that value if found.
  • No match found: None of the numbers in this list are evenly divisible by 7.
  • Fallback behavior: Since int is a value type, FirstOrDefault() falls back to its default value, 0, instead of throwing an exception like First() would.
  • Why this matters: This makes FirstOrDefault() a safer choice than First() whenever a match isn't guaranteed to exist.

Exercise 10: Finding the Last Match

Practice Problem: Find the last word in a list that ends with the letter 'e'.

Purpose: This exercise helps you practice using LastOrDefault() to find the final element matching a condition, scanning the sequence for every match but keeping only the last one.

Given Input: words = new List<string> { "apple", "banana", "grape", "cherry", "orange", "kiwi" }

Expected Output:

Finding the last word that ends with the letter 'e':
Result: orange
Search completed successfully.
▼ Hint
  • Use LastOrDefault() to find the last matching element instead of the first.
  • The condition should check w.EndsWith("e").
  • LastOrDefault() safely returns null (for strings) if no match is found, rather than throwing an exception.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class LastMatchingWordFinder
    {
        static void Main(string[] args)
        {
            List<string> words = new List<string> { "apple", "banana", "grape", "cherry", "orange", "kiwi" };
            Console.WriteLine("Finding the last word that ends with the letter 'e':");
            string result = words.LastOrDefault(w => w.EndsWith("e"));
            Console.WriteLine($"Result: {result}");
            Console.WriteLine("Search completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • words.LastOrDefault(w => w.EndsWith("e")): Scans the list for every word ending in "e", but keeps only the last one found instead of the first.
  • w.EndsWith("e"): Checks whether each string's final character is "e".
  • LastOrDefault() (instead of Last()): Returns null instead of throwing an exception if no word in the list matched the condition, since string is a reference type.

Exercise 11: Converting Strings to Uppercase

Practice Problem: Transform a list of lowercase strings into uppercase.

Purpose: This exercise helps you practice using Select() to apply a simple transformation, calling a built-in string method, to every element in a sequence.

Given Input: words = new List<string> { "apple", "banana", "cherry" }

Expected Output:

Converting words to uppercase:
Result: APPLE, BANANA, CHERRY
Conversion completed successfully.
▼ Hint
  • Use Select() to transform each string.
  • Call .ToUpper() on each word inside the lambda.
  • Convert the result to a list with ToList().
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class UppercaseConverter
    {
        static void Main(string[] args)
        {
            List<string> words = new List<string> { "apple", "banana", "cherry" };
            Console.WriteLine("Converting words to uppercase:");
            List<string> upperWords = words.Select(w => w.ToUpper()).ToList();
            Console.WriteLine($"Result: {string.Join(", ", upperWords)}");
            Console.WriteLine("Conversion completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • words.Select(w => w.ToUpper()): Projects each string in the list into its uppercase equivalent.
  • w.ToUpper(): Converts an individual string to uppercase within the lambda.
  • .ToList(): Converts the transformed sequence into a new List<string>, leaving the original list unchanged.

Exercise 12: Projecting Object Properties

Practice Problem: Given a list of User objects (with Id, Name, Email), project a new list containing only the Email strings.

Purpose: This exercise helps you practice using Select() to pull a single property out of a list of custom objects, producing a simpler, more focused collection.

Given Input: Users Alice, Bob, and Charlie, each with an Id, Name, and Email

Expected Output:

Extracting email addresses from user objects:
Emails: alice@example.com, bob@example.com, charlie@example.com
Projection completed successfully.
▼ Hint
  • Use Select() with a lambda that accesses only the Email property.
  • The lambda should be u => u.Email.
  • Convert the projected sequence to a list with ToList().
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class User
    {
        public int Id;
        public string Name;
        public string Email;
        public User(int id, string name, string email)
        {
            Id = id;
            Name = name;
            Email = email;
        }
    }
    class EmailProjector
    {
        static void Main(string[] args)
        {
            List<User> users = new List<User>
            {
                new User(1, "Alice", "alice@example.com"),
                new User(2, "Bob", "bob@example.com"),
                new User(3, "Charlie", "charlie@example.com")
            };
            Console.WriteLine("Extracting email addresses from user objects:");
            List<string> emails = users.Select(u => u.Email).ToList();
            Console.WriteLine($"Emails: {string.Join(", ", emails)}");
            Console.WriteLine("Projection completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • users.Select(u => u.Email): Projects each User object down to just its Email property, discarding the Id and Name.
  • u.Email: Accesses a single property of each object within the lambda.
  • Result: A new List<string>, entirely separate from the original list of User objects.

Exercise 13: Creating Anonymous Types

Practice Problem: Convert a list of Product objects into a list of anonymous types containing only ProductName and CalculatedTax (Price * 0.15).

Purpose: This exercise helps you practice projecting into an anonymous type, a quick way to reshape data into a new, temporary structure without defining a separate class.

Given Input: Laptop ($1000), Mouse ($20), Keyboard ($50)

Expected Output:

Projecting products into anonymous types with calculated tax:
Laptop: Tax = $150.00
Mouse: Tax = $3.00
Keyboard: Tax = $7.50
Anonymous type projection completed successfully.
▼ Hint
  • Use Select() with a lambda that returns new { ... } instead of an existing class.
  • Give the anonymous type two properties: ProductName and CalculatedTax.
  • Calculate CalculatedTax as p.Price * 0.15m directly inside the projection.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class Product
    {
        public string Name;
        public decimal Price;
        public Product(string name, decimal price)
        {
            Name = name;
            Price = price;
        }
    }
    class AnonymousTypeDemo
    {
        static void Main(string[] args)
        {
            List<Product> products = new List<Product>
            {
                new Product("Laptop", 1000m),
                new Product("Mouse", 20m),
                new Product("Keyboard", 50m)
            };
            Console.WriteLine("Projecting products into anonymous types with calculated tax:");
            var productTaxInfo = products.Select(p => new
            {
                ProductName = p.Name,
                CalculatedTax = p.Price * 0.15m
            });
            foreach (var item in productTaxInfo)
            {
                Console.WriteLine($"{item.ProductName}: Tax = ${item.CalculatedTax}");
            }
            Console.WriteLine("Anonymous type projection completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • products.Select(p => new { ProductName = ..., CalculatedTax = ... }): Projects each Product into a new anonymous type containing only the two computed fields needed.
  • new { ... } (without a class name): Creates an anonymous type on the fly, useful when you only need a temporary shape for your data.
  • p.Price * 0.15m: Calculates the tax for each product as part of the projection itself.
  • var productTaxInfo: Since anonymous types have no explicit name, var is required to hold the result.

Exercise 14: Flattening Nested Lists

Practice Problem: Given a list of Department objects, where each department has a List<Employee>, flatten this into a single IEnumerable<Employee>.

Purpose: This exercise helps you practice using SelectMany() to flatten a collection of collections into one single sequence, rather than a sequence of lists.

Given Input: Engineering (Alice, Bob), Sales (Charlie), Marketing (Dave, Eve)

Expected Output:

Flattening all employees across every department:
All Employees: Alice, Bob, Charlie, Dave, Eve
Flattening completed successfully.
▼ Hint
  • Use SelectMany() instead of Select() to flatten a collection of collections.
  • The lambda should return each department's Employees list: d => d.Employees.
  • The result is a single flat IEnumerable<Employee>, not a list of lists.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class Employee
    {
        public string Name;
        public Employee(string name)
        {
            Name = name;
        }
    }
    class Department
    {
        public string Name;
        public List<Employee> Employees;
        public Department(string name, List<Employee> employees)
        {
            Name = name;
            Employees = employees;
        }
    }
    class DepartmentFlattener
    {
        static void Main(string[] args)
        {
            List<Department> departments = new List<Department>
            {
                new Department("Engineering", new List<Employee> { new Employee("Alice"), new Employee("Bob") }),
                new Department("Sales", new List<Employee> { new Employee("Charlie") }),
                new Department("Marketing", new List<Employee> { new Employee("Dave"), new Employee("Eve") })
            };
            Console.WriteLine("Flattening all employees across every department:");
            IEnumerable<Employee> allEmployees = departments.SelectMany(d => d.Employees);
            Console.WriteLine($"All Employees: {string.Join(", ", allEmployees.Select(e => e.Name))}");
            Console.WriteLine("Flattening completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • departments.SelectMany(d => d.Employees): Instead of returning a list of lists, SelectMany() combines every department's Employees collection into a single, flat sequence.
  • d.Employees: For each department, this selects its nested list of employees, which SelectMany() then flattens automatically.
  • IEnumerable<Employee> allEmployees: The result type is a single flat sequence of Employee objects, regardless of how many departments or employees per department existed.
  • Why not Select(): Using Select() instead of SelectMany() here would have produced a sequence of lists instead of a single flattened sequence.

Exercise 15: Finding Unique Characters

Practice Problem: Given a sentence, extract a list of all unique characters used, sorted alphabetically.

Purpose: This exercise helps you practice treating a string as a sequence of characters in LINQ, chaining Where(), Distinct(), and OrderBy() together.

Given Input: sentence = "the quick brown fox"

Expected Output:

Extracting unique characters from "the quick brown fox":
Unique Characters: b, c, e, f, h, i, k, n, o, q, r, t, u, w, x
Extraction completed successfully.
▼ Hint
  • Remember that a string can be enumerated directly as a sequence of characters in LINQ.
  • Use Where() to exclude spaces, then Distinct() to remove duplicate letters.
  • Finish with OrderBy(c => c) to sort the remaining characters alphabetically.
▼ Solution & Explanation
using System;
using System.Linq;

namespace LinqUtilities
{
    class UniqueCharacterFinder
    {
        static void Main(string[] args)
        {
            string sentence = "the quick brown fox";

            Console.WriteLine($"Extracting unique characters from \"{sentence}\":");

            var uniqueChars = sentence
                .Where(c => c != ' ')
                .Distinct()
                .OrderBy(c => c)
                .ToList();

            Console.WriteLine($"Unique Characters: {string.Join(", ", uniqueChars)}");
            Console.WriteLine("Extraction completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • sentence.Where(c => c != ' '): Since a string can be treated as a sequence of characters, this filters out spaces before processing.
  • .Distinct(): Removes any duplicate characters, keeping only the first occurrence of each.
  • .OrderBy(c => c): Sorts the remaining unique characters into alphabetical order.
  • Why chain them: These three operations together produce exactly the unique letters used in the sentence, sorted alphabetically.

Exercise 16: Projecting with Index

Practice Problem: Given a list of strings, return a new string array where each item looks like "Index: {index}, Value: {value}".

Purpose: This exercise helps you practice using the overload of Select() that provides each element's position, useful when the index itself is part of the output.

Given Input: items = new List<string> { "Red", "Green", "Blue" }

Expected Output:

Projecting each item with its index:
Index: 0, Value: Red
Index: 1, Value: Green
Index: 2, Value: Blue
Index projection completed successfully.
▼ Hint
  • Use the overload of Select() that takes a lambda with two parameters: (value, index).
  • Build a formatted string inside the lambda using both parameters.
  • Convert the result to an array with ToArray().
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class IndexProjector
    {
        static void Main(string[] args)
        {
            List<string> items = new List<string> { "Red", "Green", "Blue" };
            Console.WriteLine("Projecting each item with its index:");
            string[] result = items
                .Select((value, index) => $"Index: {index}, Value: {value}")
                .ToArray();
            foreach (string line in result)
            {
                Console.WriteLine(line);
            }
            Console.WriteLine("Index projection completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • items.Select((value, index) => ...): Uses the overload of Select() that provides both the element and its zero-based position in the sequence.
  • (value, index) =>: The lambda takes two parameters instead of one, the item itself and its index.
  • $"Index: {index}, Value: {value}": Combines both pieces of information into a single formatted string for each element.
  • .ToArray(): Converts the projected sequence into a string array.

Exercise 17: Zipping Two Arrays Together

Practice Problem: Use Zip to combine an array of first names and an array of last names into a single "First Last" string array.

Purpose: This exercise helps you practice using Zip() to pair up elements from two sequences by their position and combine them into a single result.

Given Input: firstNames = "John", "Jane", "Jim", lastNames = "Doe", "Smith", "Brown"

Expected Output:

Combining first and last names using Zip:
Full Names: John Doe, Jane Smith, Jim Brown
Zipping completed successfully.
▼ Hint
  • Use Zip() to combine two sequences element by element based on their position.
  • Pass the second array and a lambda that combines each pair: (first, last) => $"{first} {last}".
  • The result pairs up elements at matching positions from both arrays.
▼ Solution & Explanation
using System;
using System.Linq;

namespace LinqUtilities
{
    class NameZipper
    {
        static void Main(string[] args)
        {
            string[] firstNames = { "John", "Jane", "Jim" };
            string[] lastNames = { "Doe", "Smith", "Brown" };

            Console.WriteLine("Combining first and last names using Zip:");

            string[] fullNames = firstNames
                .Zip(lastNames, (first, last) => $"{first} {last}")
                .ToArray();

            Console.WriteLine($"Full Names: {string.Join(", ", fullNames)}");
            Console.WriteLine("Zipping completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • firstNames.Zip(lastNames, (first, last) => ...): Pairs up elements from two sequences by their position, combining the first element of each, then the second element of each, and so on.
  • (first, last) => $"{first} {last}": The lambda defines how each paired-up pair of elements should be combined into a single result.
  • Mismatched lengths: If the two arrays had different lengths, Zip() would only produce as many pairs as the shorter sequence has elements.
  • .ToArray(): Converts the resulting sequence of combined names into a string array.

Exercise 18: Extracting Unique Email Domains

Practice Problem: Given a list of email addresses, extract a unique list of email domains.

Purpose: This exercise helps you practice combining string parsing with Select() and Distinct() to extract and deduplicate a derived piece of data.

Given Input: emails = "alice@gmail.com", "bob@yahoo.com", "charlie@gmail.com", "dave@outlook.com", "eve@yahoo.com"

Expected Output:

Extracting unique email domains:
Domains: gmail.com, yahoo.com, outlook.com
Domain extraction completed successfully.
▼ Hint
  • Use Select() with a lambda that splits each email on '@' and takes the second part: email.Split('@')[1].
  • Chain Distinct() after Select() to remove duplicate domains.
  • Convert the result to a list with ToList().
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class DomainExtractor
    {
        static void Main(string[] args)
        {
            List<string> emails = new List<string>
            {
                "alice@gmail.com",
                "bob@yahoo.com",
                "charlie@gmail.com",
                "dave@outlook.com",
                "eve@yahoo.com"
            };
            Console.WriteLine("Extracting unique email domains:");
            List<string> domains = emails
                .Select(email => email.Split('@')[1])
                .Distinct()
                .ToList();
            Console.WriteLine($"Domains: {string.Join(", ", domains)}");
            Console.WriteLine("Domain extraction completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • email.Split('@')[1]: Splits each email address on the '@' character and takes the second part, which is the domain.
  • .Select(email => ...): Applies this splitting logic to every email address in the list, projecting each one down to just its domain.
  • .Distinct(): Removes duplicate domains, since multiple emails often share the same provider.
  • Result: The final list contains each domain exactly once, in the order it was first encountered.

Exercise 19: Flattening a 2D Array

Practice Problem: Flatten a 2D integer array (int[][]) into a 1D sequence of integers.

Purpose: This exercise helps you practice using SelectMany() on a jagged array, where each row can have a different length, to produce one flat sequence.

Given Input: matrix = { {1, 2, 3}, {4, 5}, {6, 7, 8, 9} }

Expected Output:

Flattening a jagged 2D array into a single sequence:
Flattened: 1, 2, 3, 4, 5, 6, 7, 8, 9
Flattening completed successfully.
▼ Hint
  • Use SelectMany() to flatten the array of arrays into a single sequence.
  • The lambda can simply return each row directly: row => row.
  • Convert the result to an array with ToArray().
▼ Solution & Explanation
using System;
using System.Linq;

namespace LinqUtilities
{
    class MatrixFlattener
    {
        static void Main(string[] args)
        {
            int[][] matrix =
            {
                new int[] { 1, 2, 3 },
                new int[] { 4, 5 },
                new int[] { 6, 7, 8, 9 }
            };

            Console.WriteLine("Flattening a jagged 2D array into a single sequence:");

            int[] flattened = matrix.SelectMany(row => row).ToArray();

            Console.WriteLine($"Flattened: {string.Join(", ", flattened)}");
            Console.WriteLine("Flattening completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • int[][] matrix: A jagged array, an array where each row is itself a separate array, and rows can have different lengths.
  • matrix.SelectMany(row => row): Combines every row's elements into a single flat sequence, rather than a sequence of arrays.
  • row => row: Since each row is already a sequence of integers, the lambda simply returns it directly for SelectMany() to flatten.
  • .ToArray(): Converts the flattened sequence into a single one-dimensional int array.

Exercise 20: Extracting File Extensions

Practice Problem: Given a list of file paths, extract just the file extensions dynamically.

Purpose: This exercise helps you practice combining LastIndexOf() and Substring() inside a Select() projection to extract a variable-length piece of each string.

Given Input: filePaths = "document.txt", "image.png", "archive.zip", "notes.txt", "photo.jpeg"

Expected Output:

Extracting file extensions dynamically:
Extensions: .txt, .png, .zip, .txt, .jpeg
Extraction completed successfully.
▼ Hint
  • Use path.LastIndexOf('.') to find where the extension begins.
  • Use path.Substring() starting from that index to extract the extension, including the period.
  • Apply this inside a Select() lambda to process the whole list.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class FileExtensionExtractor
    {
        static void Main(string[] args)
        {
            List<string> filePaths = new List<string>
            {
                "document.txt",
                "image.png",
                "archive.zip",
                "notes.txt",
                "photo.jpeg"
            };
            Console.WriteLine("Extracting file extensions dynamically:");
            List<string> extensions = filePaths
                .Select(path => path.Substring(path.LastIndexOf('.')))
                .ToList();
            Console.WriteLine($"Extensions: {string.Join(", ", extensions)}");
            Console.WriteLine("Extraction completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • path.LastIndexOf('.'): Finds the position of the final period in the file name, which marks the start of the extension.
  • path.Substring(...): Extracts everything from that position to the end of the string, capturing the extension along with its leading period.
  • .Select(path => ...): Applies this extraction logic to every file path in the list.
  • Why LastIndexOf(): Using LastIndexOf() rather than IndexOf() correctly handles file names that contain multiple periods, such as "archive.tar.gz".

Exercise 21: Summing Squares of Odd Numbers

Practice Problem: Calculate the sum of the squares of all odd numbers in a list.

Purpose: This exercise helps you practice using Sum() with a selector, transforming and totaling values in a single step instead of chaining a separate Select() beforehand.

Given Input: numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }

Expected Output:

Calculating the sum of squares of all odd numbers:
Sum of Squares = 165
Calculation completed successfully.
▼ Hint
  • Use Where() to filter down to only the odd numbers first.
  • Chain Sum() with a lambda that squares each number: n => n * n.
  • Sum()'s selector overload lets you transform and total values in a single step.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class SumOfSquaresCalculator
    {
        static void Main(string[] args)
        {
            List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            Console.WriteLine("Calculating the sum of squares of all odd numbers:");
            int sumOfSquares = numbers
                .Where(n => n % 2 != 0)
                .Sum(n => n * n);
            Console.WriteLine($"Sum of Squares = {sumOfSquares}");
            Console.WriteLine("Calculation completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • numbers.Where(n => n % 2 != 0): Filters the list down to only odd numbers first.
  • .Sum(n => n * n): Squares each remaining number and adds all the squares together in a single step.
  • Why this works: Combining a selector directly inside Sum() avoids needing a separate Select() call before it.

Exercise 22: Averaging Prices with a Condition

Practice Problem: Given a list of Book objects, find the average price of books published after the year 2010.

Purpose: This exercise helps you practice combining Where() with Average(), filtering a collection before aggregating it.

Given Input: Clean Code (2008, $35), The Pragmatic Programmer (2019, $40), C# in Depth (2019, $45), Design Patterns (1994, $50), Refactoring (2018, $42)

Expected Output:

Calculating average price of books published after 2010:
Average Price = $42.33
Calculation completed successfully.
▼ Hint
  • Use Where() to filter books published after the year 2010.
  • Chain Average() with a lambda that selects the Price property: b => b.Price.
  • Average() computes the mean directly over the filtered results.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class Book
    {
        public string Title;
        public int Year;
        public decimal Price;
        public Book(string title, int year, decimal price)
        {
            Title = title;
            Year = year;
            Price = price;
        }
    }
    class AveragePriceCalculator
    {
        static void Main(string[] args)
        {
            List<Book> books = new List<Book>
            {
                new Book("Clean Code", 2008, 35m),
                new Book("The Pragmatic Programmer", 2019, 40m),
                new Book("C# in Depth", 2019, 45m),
                new Book("Design Patterns", 1994, 50m),
                new Book("Refactoring", 2018, 42m)
            };
            Console.WriteLine("Calculating average price of books published after 2010:");
            decimal averagePrice = books
                .Where(b => b.Year > 2010)
                .Average(b => b.Price);
            Console.WriteLine($"Average Price = ${averagePrice:F2}");
            Console.WriteLine("Calculation completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • books.Where(b => b.Year > 2010): Filters the list down to only books published after 2010.
  • .Average(b => b.Price): Calculates the average of the Price property across the filtered books.
  • Why this works: Because Average() accepts a selector directly, there's no need for a separate Select() step before calling it.

Exercise 23: Finding Min and Max Price

Practice Problem: Find the minimum and maximum price in a list of Product objects.

Purpose: This exercise helps you practice using Min() and Max() with a selector to find the smallest and largest value of a specific property across a collection.

Given Input: Laptop ($999), Mouse ($15), Monitor ($250), Keyboard ($45)

Expected Output:

Finding the cheapest and most expensive product:
Cheapest Price = $15
Most Expensive Price = $999
Price range search completed successfully.
▼ Hint
  • Use Min() with a lambda selecting the Price property to find the cheapest product's price.
  • Use Max() the same way to find the most expensive product's price.
  • Both methods scan the whole collection in a single pass to find their result.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class Product
    {
        public string Name;
        public decimal Price;
        public Product(string name, decimal price)
        {
            Name = name;
            Price = price;
        }
    }
    class PriceRangeFinder
    {
        static void Main(string[] args)
        {
            List<Product> products = new List<Product>
            {
                new Product("Laptop", 999m),
                new Product("Mouse", 15m),
                new Product("Monitor", 250m),
                new Product("Keyboard", 45m)
            };
            Console.WriteLine("Finding the cheapest and most expensive product:");
            decimal minPrice = products.Min(p => p.Price);
            decimal maxPrice = products.Max(p => p.Price);
            Console.WriteLine($"Cheapest Price = ${minPrice}");
            Console.WriteLine($"Most Expensive Price = ${maxPrice}");
            Console.WriteLine("Price range search completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • products.Min(p => p.Price): Scans every product and returns the smallest Price value found.
  • products.Max(p => p.Price): Scans every product and returns the largest Price value found.
  • Why a selector: Both methods accept a selector, so they can compute the minimum or maximum of a specific property, rather than requiring the objects themselves to be directly comparable.

Exercise 24: Counting Matching Elements

Practice Problem: Count how many elements in a list of strings contain the word "LINQ".

Purpose: This exercise helps you practice using Count() with a predicate, which filters and counts in a single operation instead of chaining Where().Count().

Given Input: "I love LINQ", "This has nothing", "LINQ is powerful", "Another sentence", "LINQ makes life easier"

Expected Output:

Counting how many sentences mention "LINQ":
Count = 3
Counting completed successfully.
▼ Hint
  • Use Count() with a lambda instead of Where().Count(), since it does both in one step.
  • The condition should check s.Contains("LINQ").
  • Count() with a predicate returns the number of matching elements directly as an int.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class ConditionCounter
    {
        static void Main(string[] args)
        {
            List<string> sentences = new List<string>
            {
                "I love LINQ",
                "This has nothing",
                "LINQ is powerful",
                "Another sentence",
                "LINQ makes life easier"
            };
            Console.WriteLine("Counting how many sentences mention \"LINQ\":");
            int count = sentences.Count(s => s.Contains("LINQ"));
            Console.WriteLine($"Count = {count}");
            Console.WriteLine("Counting completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • sentences.Count(s => s.Contains("LINQ")): Counts how many elements in the list satisfy the given condition, without needing to first filter and then measure the length separately.
  • s.Contains("LINQ"): Checks whether each string includes the substring "LINQ" anywhere within it.
  • Why this works: Count()'s selector overload combines filtering and counting into a single operation.

Exercise 25: Joining Words with Aggregate

Practice Problem: Use the Aggregate operator to concatenate a list of words into a single comma-separated sentence, without a trailing comma.

Purpose: This exercise helps you practice Aggregate(), which applies a function cumulatively over a sequence, carrying forward an accumulated result from one element to the next.

Given Input: words = new List<string> { "apple", "banana", "cherry", "date" }

Expected Output:

Joining words into a comma-separated sentence using Aggregate:
Result: apple, banana, cherry, date
Concatenation completed successfully.
▼ Hint
  • Use Aggregate() with a lambda that takes two parameters: the accumulated result so far and the next element.
  • Combine them with (current, next) => current + ", " + next.
  • Since Aggregate() only inserts the separator between elements, there's no trailing comma to worry about.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class WordJoiner
    {
        static void Main(string[] args)
        {
            List<string> words = new List<string> { "apple", "banana", "cherry", "date" };
            Console.WriteLine("Joining words into a comma-separated sentence using Aggregate:");
            string sentence = words.Aggregate((current, next) => current + ", " + next);
            Console.WriteLine($"Result: {sentence}");
            Console.WriteLine("Concatenation completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • words.Aggregate((current, next) => ...): Applies a function cumulatively over the sequence, carrying forward an accumulated result from one element to the next.
  • current: Holds the combined result built so far, starting as the first word in the list.
  • next: Represents each subsequent word being folded into the accumulated result.
  • current + ", " + next: Appends a comma and space before adding each new word, naturally avoiding a trailing comma since the separator is only added between elements, never after the last one.

Exercise 26: Calculating Factorial with LINQ

Practice Problem: Use LINQ (Enumerable.Range and Aggregate) to calculate the factorial of a given number n.

Purpose: This exercise helps you practice combining Enumerable.Range() with the seeded overload of Aggregate(), which lets you specify an explicit starting value for the accumulation.

Given Input: n = 5

Expected Output:

Calculating the factorial of 5 using LINQ:
Factorial = 120
Calculation completed successfully.
▼ Hint
  • Use Enumerable.Range(1, n) to generate the numbers from 1 to n.
  • Use the overload of Aggregate() that takes a seed value, starting at 1L.
  • Multiply the accumulator by each number in the lambda: (accumulator, current) => accumulator * current.
▼ Solution & Explanation
using System;
using System.Linq;

namespace LinqUtilities
{
    class FactorialCalculator
    {
        static void Main(string[] args)
        {
            int n = 5;

            Console.WriteLine($"Calculating the factorial of {n} using LINQ:");

            long factorial = Enumerable.Range(1, n).Aggregate(1L, (accumulator, current) => accumulator * current);

            Console.WriteLine($"Factorial = {factorial}");
            Console.WriteLine("Calculation completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • Enumerable.Range(1, n): Generates a sequence of integers from 1 up to n, exactly the numbers needed to compute a factorial.
  • Aggregate(1L, (accumulator, current) => accumulator * current): Starts with a seed value of 1, then multiplies it by each number in the sequence in turn.
  • The seed value 1L: Provides the starting point for the accumulation and also determines that the result type is long, allowing for larger factorial values than int could hold.
  • Why a seed: This overload of Aggregate(), which accepts an explicit seed, is useful whenever the accumulation needs a specific starting value rather than just the sequence's first element.

Exercise 27: Summing Department Salaries

Practice Problem: Calculate the total monthly salary expense for a specific department from a list of Employee objects.

Purpose: This exercise helps you practice chaining Where() and Sum() together to total a property across only a filtered subset of a collection.

Given Input: Alice (Engineering, $8500), Bob (Sales, $6000), Charlie (Engineering, $9200), Dave (Marketing, $5500), Eve (Engineering, $7800)

Expected Output:

Calculating total monthly salary for the Engineering department:
Total Salary = $25500
Calculation completed successfully.
▼ Hint
  • Use Where() to filter employees down to the target department.
  • Chain Sum() with a lambda selecting the Salary property: e => e.Salary.
  • The result is the total salary expense for just that department.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class Employee
    {
        public string Name;
        public string Department;
        public decimal Salary;
        public Employee(string name, string department, decimal salary)
        {
            Name = name;
            Department = department;
            Salary = salary;
        }
    }
    class SalaryBillCalculator
    {
        static void Main(string[] args)
        {
            List<Employee> employees = new List<Employee>
            {
                new Employee("Alice", "Engineering", 8500m),
                new Employee("Bob", "Sales", 6000m),
                new Employee("Charlie", "Engineering", 9200m),
                new Employee("Dave", "Marketing", 5500m),
                new Employee("Eve", "Engineering", 7800m)
            };
            Console.WriteLine("Calculating total monthly salary for the Engineering department:");
            decimal totalSalary = employees
                .Where(e => e.Department == "Engineering")
                .Sum(e => e.Salary);
            Console.WriteLine($"Total Salary = ${totalSalary}");
            Console.WriteLine("Calculation completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • employees.Where(e => e.Department == "Engineering"): Filters the list down to only employees belonging to the target department.
  • .Sum(e => e.Salary): Adds together the Salary property of every employee that passed the filter.
  • Why chain them: Chaining Where() and Sum() together produces the total salary bill for just that one department, without affecting the original list.

Exercise 28: Counting Vowels with LINQ

Practice Problem: Given a string, count how many vowels (a, e, i, o, u) it contains using LINQ.

Purpose: This exercise helps you practice treating a string as a character sequence and using Count() with a predicate that checks membership in a small reference set.

Given Input: text = "Programming in LINQ is enjoyable"

Expected Output:

Counting vowels in "Programming in LINQ is enjoyable":
Vowel Count = 10
Counting completed successfully.
▼ Hint
  • Convert the string to lowercase first with ToLower().
  • Use Count() with a lambda that checks "aeiou".Contains(c) for each character.
  • A string can be enumerated character by character, so LINQ methods like Count() work on it directly.
▼ Solution & Explanation
using System;
using System.Linq;

namespace LinqUtilities
{
    class VowelCounter
    {
        static void Main(string[] args)
        {
            string text = "Programming in LINQ is enjoyable";

            Console.WriteLine($"Counting vowels in \"{text}\":");

            int vowelCount = text.ToLower().Count(c => "aeiou".Contains(c));

            Console.WriteLine($"Vowel Count = {vowelCount}");
            Console.WriteLine("Counting completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • text.ToLower(): Converts the string to lowercase first, so vowel comparisons only need to check one case.
  • .Count(c => "aeiou".Contains(c)): Counts how many characters in the string are found within the "aeiou" reference string.
  • "aeiou".Contains(c): Checks each character in text against the five vowels in a single, compact condition.
  • Why this works: Treating the string as a sequence of characters lets Count() work directly on it, just like it would on any other LINQ sequence.

Exercise 29: Multiplying Numbers with Aggregate

Practice Problem: Calculate the product of all non-zero numbers in an array.

Purpose: This exercise helps you practice using Aggregate() to compute a running product, since LINQ has no built-in Product() method the way it has Sum().

Given Input: numbers = new int[] { 2, 0, 3, 4, 0, 5 }

Expected Output:

Calculating the product of all non-zero numbers:
Product = 120
Calculation completed successfully.
▼ Hint
  • Use Where() to filter out any zero values before multiplying.
  • LINQ has no built-in Product() method, so use Aggregate() with a seed of 1L instead.
  • Multiply the accumulator by each number in the lambda: (accumulator, current) => accumulator * current.
▼ Solution & Explanation
using System;
using System.Linq;

namespace LinqUtilities
{
    class ProductCalculator
    {
        static void Main(string[] args)
        {
            int[] numbers = { 2, 0, 3, 4, 0, 5 };

            Console.WriteLine("Calculating the product of all non-zero numbers:");

            long product = numbers
                .Where(n => n != 0)
                .Aggregate(1L, (accumulator, current) => accumulator * current);

            Console.WriteLine($"Product = {product}");
            Console.WriteLine("Calculation completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • numbers.Where(n => n != 0): Filters out any zero values first, since multiplying by zero would collapse the entire product to zero.
  • .Aggregate(1L, (accumulator, current) => accumulator * current): Starts with a seed value of 1 and multiplies it by each remaining number in turn.
  • The seed value of 1: Ensures the multiplication starts correctly, since 1 is the multiplicative identity, just as 0 is used as the seed for a sum.
  • Why Aggregate(): There's no built-in Product() method in LINQ, so Aggregate() is the standard way to compute a running product.

Exercise 30: Finding the Longest Word

Practice Problem: Find the longest word in an array of strings using MaxBy.

Purpose: This exercise helps you practice using MaxBy(), which returns the original element with the largest selected value, rather than Max(), which only returns the value itself.

Given Input: words = new string[] { "cat", "elephant", "dog", "hippopotamus", "ox" }

Expected Output:

Finding the longest word in the array:
Longest Word: hippopotamus
Search completed successfully.
▼ Hint
  • Use MaxBy() with a lambda selecting the Length property: w => w.Length.
  • Unlike Max(), MaxBy() returns the original element, not just the maximum value.
  • This directly gives you the longest word itself, not just its length.
▼ Solution & Explanation
using System;
using System.Linq;

namespace LinqUtilities
{
    class LongestWordFinder
    {
        static void Main(string[] args)
        {
            string[] words = { "cat", "elephant", "dog", "hippopotamus", "ox" };

            Console.WriteLine("Finding the longest word in the array:");

            string longestWord = words.MaxBy(w => w.Length);

            Console.WriteLine($"Longest Word: {longestWord}");
            Console.WriteLine("Search completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • words.MaxBy(w => w.Length): Scans the array and returns the element that produces the largest value for the given selector, in this case, the word with the greatest Length.
  • Difference from Max(): Unlike Max(), which would return the largest Length value itself (a number), MaxBy() returns the original element that has that maximum value.
  • Why this matters: This makes MaxBy() the more direct choice whenever you need the item itself, rather than just the value used to compare it.

Exercise 31: Grouping People by Age

Practice Problem: Given a list of Person objects, group them by their Age.

Purpose: This exercise helps you practice the basics of GroupBy(), organizing a flat list of objects into groups that share a common property value.

Given Input: Alice (30), Bob (25), Charlie (30), Dave (25), Eve (35)

Expected Output:

Grouping people by age:
Age 30: Alice, Charlie
Age 25: Bob, Dave
Age 35: Eve
Grouping completed successfully.
▼ Hint
  • Use GroupBy() with a lambda selecting the Age property.
  • Loop through the resulting groups; each one has a Key (the age) and a collection of matching people.
  • Use group.Select() to pull out just the names within each group.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class Person
    {
        public string Name;
        public int Age;
        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }
    }
    class AgeGrouper
    {
        static void Main(string[] args)
        {
            List<Person> people = new List<Person>
            {
                new Person("Alice", 30),
                new Person("Bob", 25),
                new Person("Charlie", 30),
                new Person("Dave", 25),
                new Person("Eve", 35)
            };
            Console.WriteLine("Grouping people by age:");
            var groupedByAge = people.GroupBy(p => p.Age);
            foreach (var group in groupedByAge)
            {
                Console.WriteLine($"Age {group.Key}: {string.Join(", ", group.Select(p => p.Name))}");
            }
            Console.WriteLine("Grouping completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • people.GroupBy(p => p.Age): Organizes the list into groups, one for each distinct Age value found.
  • group.Key: Within each group, this holds the Age value that all the people in that group share.
  • group.Select(p => p.Name): Projects each group down to just the names of the people inside it.
  • Order of groups: Groups appear in the order their key was first encountered while scanning the original list, not sorted numerically.

Exercise 32: Counting Words by Length

Practice Problem: Group a list of words by their length, and display the length along with the count of words that match that length.

Purpose: This exercise helps you practice combining GroupBy() with Count() to summarize how many items fall into each group.

Given Input: words = "cat", "dog", "fish", "bird", "ant", "lion", "owl", "bee"

Expected Output:

Grouping words by length and counting each group:
Length 3: 5 words
Length 4: 3 words
Counting completed successfully.
▼ Hint
  • Use GroupBy() with a lambda selecting each word's Length.
  • For each group, call group.Count() to get how many words share that length.
  • Project the results into an anonymous object containing the length and its count.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class WordLengthCounter
    {
        static void Main(string[] args)
        {
            List<string> words = new List<string> { "cat", "dog", "fish", "bird", "ant", "lion", "owl", "bee" };
            Console.WriteLine("Grouping words by length and counting each group:");
            var groupedByLength = words
                .GroupBy(w => w.Length)
                .Select(group => new
                {
                    Length = group.Key,
                    Count = group.Count()
                });
            foreach (var entry in groupedByLength)
            {
                Console.WriteLine($"Length {entry.Length}: {entry.Count} words");
            }
            Console.WriteLine("Counting completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • words.GroupBy(w => w.Length): Groups the words based on their character count.
  • group.Count(): Counts how many words fall into each individual group.
  • new { Length = group.Key, Count = group.Count() }: Projects each group into an anonymous type pairing the length with how many words share that length.

Exercise 33: Joining Students and Courses

Practice Problem: Given a list of Student objects and Course objects, perform an inner join to list student names alongside their courses.

Purpose: This exercise helps you practice Join(), LINQ's equivalent of a SQL inner join, matching elements from two sequences based on a shared key.

Given Input: Students: (1, Alice), (2, Bob), (3, Charlie). Courses: (1, Math), (1, Science), (2, History), (4, Art)

Expected Output:

Performing an inner join between students and courses:
Alice: Math
Alice: Science
Bob: History
Inner join completed successfully.
▼ Hint
  • Use Join(), passing the second collection, a key selector for each side, and a result selector.
  • The key selectors should return StudentId from both the student and the course.
  • Only pairs where both a student and a course share the same StudentId appear in the result.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class Student
    {
        public int StudentId;
        public string Name;
        public Student(int studentId, string name)
        {
            StudentId = studentId;
            Name = name;
        }
    }
    class Course
    {
        public int StudentId;
        public string CourseName;
        public Course(int studentId, string courseName)
        {
            StudentId = studentId;
            CourseName = courseName;
        }
    }
    class InnerJoinDemo
    {
        static void Main(string[] args)
        {
            List<Student> students = new List<Student>
            {
                new Student(1, "Alice"),
                new Student(2, "Bob"),
                new Student(3, "Charlie")
            };
            List<Course> courses = new List<Course>
            {
                new Course(1, "Math"),
                new Course(1, "Science"),
                new Course(2, "History"),
                new Course(4, "Art")
            };
            Console.WriteLine("Performing an inner join between students and courses:");
            var studentCourses = students.Join(
                courses,
                student => student.StudentId,
                course => course.StudentId,
                (student, course) => new { student.Name, course.CourseName }
            );
            foreach (var entry in studentCourses)
            {
                Console.WriteLine($"{entry.Name}: {entry.CourseName}");
            }
            Console.WriteLine("Inner join completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • students.Join(courses, student => student.StudentId, course => course.StudentId, (student, course) => ...): Matches each student to every course sharing the same StudentId, similar to a SQL inner join.
  • The two key selectors: Specify which property from each sequence should be used as the join key.
  • (student, course) => new { student.Name, course.CourseName }: Defines the shape of the combined result for each matching pair.
  • Result: Charlie has no courses and the course for StudentId 4 has no matching student, so neither appears in the result; only pairs where both sides match are included.

Exercise 34: Left Joining Employees and Departments

Practice Problem: Perform a left outer join between Employees and Departments so that employees without a department are still listed.

Purpose: This exercise helps you practice simulating a left outer join in LINQ using GroupJoin() combined with SelectMany() and DefaultIfEmpty(), since LINQ has no direct left-join method.

Given Input: Employees: Alice (Dept 10), Bob (Dept 20), Charlie (Dept 0, no matching department). Departments: 10 (Engineering), 20 (Sales)

Expected Output:

Performing a left outer join between employees and departments:
Alice: Engineering
Bob: Sales
Charlie: No Department
Left outer join completed successfully.
▼ Hint
  • Use GroupJoin() instead of Join(), so employees without a match still produce a group (an empty one).
  • Chain SelectMany() with DefaultIfEmpty() on each employee's matched departments to flatten the groups while keeping unmatched employees.
  • Use the null-conditional operator (department?.DepartmentName) combined with ?? to supply a fallback label for unmatched employees.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class Employee
    {
        public int Id;
        public string Name;
        public int DepartmentId;
        public Employee(int id, string name, int departmentId)
        {
            Id = id;
            Name = name;
            DepartmentId = departmentId;
        }
    }
    class Department
    {
        public int Id;
        public string DepartmentName;
        public Department(int id, string departmentName)
        {
            Id = id;
            DepartmentName = departmentName;
        }
    }
    class LeftOuterJoinDemo
    {
        static void Main(string[] args)
        {
            List<Employee> employees = new List<Employee>
            {
                new Employee(1, "Alice", 10),
                new Employee(2, "Bob", 20),
                new Employee(3, "Charlie", 0)
            };
            List<Department> departments = new List<Department>
            {
                new Department(10, "Engineering"),
                new Department(20, "Sales")
            };
            Console.WriteLine("Performing a left outer join between employees and departments:");
            var employeeDepartments = employees
                .GroupJoin(
                    departments,
                    employee => employee.DepartmentId,
                    department => department.Id,
                    (employee, matchedDepartments) => new { employee.Name, MatchedDepartments = matchedDepartments }
                )
                .SelectMany(
                    x => x.MatchedDepartments.DefaultIfEmpty(),
                    (x, department) => new { x.Name, DepartmentName = department?.DepartmentName ?? "No Department" }
                );
            foreach (var entry in employeeDepartments)
            {
                Console.WriteLine($"{entry.Name}: {entry.DepartmentName}");
            }
            Console.WriteLine("Left outer join completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • employees.GroupJoin(departments, ...): Groups each employee with all matching departments (zero or more), unlike Join(), which drops employees with no match at all.
  • .SelectMany(x => x.MatchedDepartments.DefaultIfEmpty(), ...): Flattens each employee's group of matches, and DefaultIfEmpty() inserts a single null placeholder if an employee had no matching department.
  • department?.DepartmentName ?? "No Department": Uses the null-conditional and null-coalescing operators together to safely fall back to a default label when there is no matching department.
  • Result: Because Charlie's DepartmentId of 0 doesn't match any real department's Id, he still appears in the result with "No Department" instead of being dropped entirely.

Exercise 35: Finding Common Numbers

Practice Problem: Find the numbers that are present in both List A and List B.

Purpose: This exercise helps you practice using Intersect() to find elements shared by two sequences in a single method call.

Given Input: listA = { 1, 2, 3, 4, 5, 6 }, listB = { 4, 5, 6, 7, 8, 9 }

Expected Output:

Finding numbers present in both lists:
Common Numbers: 4, 5, 6
Intersection completed successfully.
▼ Hint
  • Use Intersect(), passing the second list as an argument.
  • The result contains only elements that exist in both sequences.
  • Convert the result to a list with ToList().
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class IntersectionDemo
    {
        static void Main(string[] args)
        {
            List<int> listA = new List<int> { 1, 2, 3, 4, 5, 6 };
            List<int> listB = new List<int> { 4, 5, 6, 7, 8, 9 };
            Console.WriteLine("Finding numbers present in both lists:");
            List<int> common = listA.Intersect(listB).ToList();
            Console.WriteLine($"Common Numbers: {string.Join(", ", common)}");
            Console.WriteLine("Intersection completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • listA.Intersect(listB): Returns only the elements that appear in both listA and listB, using each element's default equality comparison.
  • Result: Contains each common value exactly once, even if it appeared multiple times in either original list.
  • .ToList(): Converts the resulting sequence into a concrete List<int>.

Exercise 36: Finding Missing Products

Practice Problem: Find all products in Inventory List A that are completely missing from Inventory List B.

Purpose: This exercise helps you practice using Except() to find elements that exist in one sequence but not another.

Given Input: inventoryA = "Apple", "Banana", "Cherry", "Date", "Elderberry", inventoryB = "Banana", "Date", "Fig"

Expected Output:

Finding products in Inventory A that are missing from Inventory B:
Missing Products: Apple, Cherry, Elderberry
Difference calculation completed successfully.
▼ Hint
  • Use Except(), passing the second list as an argument.
  • The result contains only elements from the first list that are not present in the second.
  • Convert the result to a list with ToList().
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class ExceptDemo
    {
        static void Main(string[] args)
        {
            List<string> inventoryA = new List<string> { "Apple", "Banana", "Cherry", "Date", "Elderberry" };
            List<string> inventoryB = new List<string> { "Banana", "Date", "Fig" };
            Console.WriteLine("Finding products in Inventory A that are missing from Inventory B:");
            List<string> missingProducts = inventoryA.Except(inventoryB).ToList();
            Console.WriteLine($"Missing Products: {string.Join(", ", missingProducts)}");
            Console.WriteLine("Difference calculation completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • inventoryA.Except(inventoryB): Returns every element from inventoryA that does not appear anywhere in inventoryB.
  • Result: Elements that exist in both lists, like "Banana" and "Date", are removed from the result entirely.
  • .ToList(): Converts the resulting sequence into a concrete List<string>.

Exercise 37: Combining Lists Without Duplicates

Practice Problem: Combine two lists of student names into a single list, ensuring no duplicate names exist in the final result.

Purpose: This exercise helps you practice using Union() to merge two sequences while automatically removing duplicates.

Given Input: listA = "Alice", "Bob", "Charlie", listB = "Bob", "Dave", "Alice", "Eve"

Expected Output:

Combining two lists of names without duplicates:
Combined Names: Alice, Bob, Charlie, Dave, Eve
Union completed successfully.
▼ Hint
  • Use Union(), passing the second list as an argument.
  • Union() automatically removes duplicates while combining both sequences.
  • Convert the result to a list with ToList().
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class UnionDemo
    {
        static void Main(string[] args)
        {
            List<string> listA = new List<string> { "Alice", "Bob", "Charlie" };
            List<string> listB = new List<string> { "Bob", "Dave", "Alice", "Eve" };
            Console.WriteLine("Combining two lists of names without duplicates:");
            List<string> combinedNames = listA.Union(listB).ToList();
            Console.WriteLine($"Combined Names: {string.Join(", ", combinedNames)}");
            Console.WriteLine("Union completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • listA.Union(listB): Combines both sequences into one, automatically removing any duplicate values that appear in either list.
  • Result: Names like "Bob" and "Alice", which appear in both lists, are included only once in the final result.
  • Order: Union() preserves the order elements were first encountered, scanning listA first and then listB for any new values.
  • .ToList(): Converts the resulting sequence into a concrete List<string>.

Exercise 38: Finding the Most Frequent Number

Practice Problem: Find the most frequently occurring integer in an array.

Purpose: This exercise helps you practice combining GroupBy(), OrderByDescending(), and First() to identify the group with the highest count.

Given Input: numbers = new int[] { 1, 3, 2, 3, 4, 3, 2, 5, 3 }

Expected Output:

Finding the most frequently occurring number:
Most Frequent Number: 3
Search completed successfully.
▼ Hint
  • Use GroupBy() with a lambda that groups each number by itself: n => n.
  • Sort the resulting groups by group.Count() in descending order.
  • Take the first group with First(), then access its Key property to get the actual number.
▼ Solution & Explanation
using System;
using System.Linq;

namespace LinqUtilities
{
    class MostFrequentElementFinder
    {
        static void Main(string[] args)
        {
            int[] numbers = { 1, 3, 2, 3, 4, 3, 2, 5, 3 };

            Console.WriteLine("Finding the most frequently occurring number:");

            int mostFrequent = numbers
                .GroupBy(n => n)
                .OrderByDescending(group => group.Count())
                .First()
                .Key;

            Console.WriteLine($"Most Frequent Number: {mostFrequent}");
            Console.WriteLine("Search completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • numbers.GroupBy(n => n): Groups every occurrence of each number together.
  • .OrderByDescending(group => group.Count()): Sorts the groups by how many elements they each contain, largest group first.
  • .First(): Selects the group with the highest count, the most frequent number.
  • .Key: Extracts the actual number value from the winning group, since Key holds the value that was grouped on.

Exercise 39: Finding the Highest Paid Employee per Department

Practice Problem: Group a list of Employee objects by Department and find the highest-paid employee in each department.

Purpose: This exercise helps you practice combining GroupBy() with MaxBy() to find the top element within each individual group, rather than across the whole collection.

Given Input: Alice (Engineering, $8500), Bob (Sales, $6000), Charlie (Engineering, $9200), Dave (Sales, $7200), Eve (Marketing, $5500)

Expected Output:

Finding the highest-paid employee in each department:
Engineering: Charlie ($9200)
Sales: Dave ($7200)
Marketing: Eve ($5500)
Search completed successfully.
▼ Hint
  • Use GroupBy() to group employees by their Department.
  • Inside a Select(), call group.MaxBy(e => e.Salary) to find the top earner in each group.
  • The result is one Employee per department, the highest-paid one in that group.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class Employee
    {
        public string Name;
        public string Department;
        public decimal Salary;
        public Employee(string name, string department, decimal salary)
        {
            Name = name;
            Department = department;
            Salary = salary;
        }
    }
    class HighestPaidFinder
    {
        static void Main(string[] args)
        {
            List<Employee> employees = new List<Employee>
            {
                new Employee("Alice", "Engineering", 8500m),
                new Employee("Bob", "Sales", 6000m),
                new Employee("Charlie", "Engineering", 9200m),
                new Employee("Dave", "Sales", 7200m),
                new Employee("Eve", "Marketing", 5500m)
            };
            Console.WriteLine("Finding the highest-paid employee in each department:");
            var highestPaidByDepartment = employees
                .GroupBy(e => e.Department)
                .Select(group => group.MaxBy(e => e.Salary));
            foreach (Employee employee in highestPaidByDepartment)
            {
                Console.WriteLine($"{employee.Department}: {employee.Name} (${employee.Salary})");
            }
            Console.WriteLine("Search completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • employees.GroupBy(e => e.Department): Groups all employees by which department they belong to.
  • group.MaxBy(e => e.Salary): Within each department's group, finds the single Employee object with the highest Salary.
  • .Select(group => ...): Applies this max-finding logic to every department group, producing one result per department.
  • Why MaxBy(): Because it returns the whole Employee object rather than just the salary value, both the employee's name and salary remain available afterward.

Exercise 40: Splitting a List into Chunks

Practice Problem: Given a large list of integers, split it into smaller sub-lists (chunks) of exactly 5 elements each, using the Chunk operator.

Purpose: This exercise helps you practice using Chunk() to break a large sequence into fixed-size batches, useful for processing large datasets in manageable pieces.

Given Input: A list of integers from 1 to 12

Expected Output:

Splitting a list of 12 numbers into chunks of 5:
Chunk 1: 1, 2, 3, 4, 5
Chunk 2: 6, 7, 8, 9, 10
Chunk 3: 11, 12
Chunking completed successfully.
▼ Hint
  • Use the Chunk(5) method directly on the collection to split it into groups of 5.
  • Each chunk is returned as its own array; the last chunk may contain fewer elements if the total isn't evenly divisible.
  • Loop through the chunks and print each one's contents.
▼ Solution & Explanation
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqUtilities
{
    class ChunkingDemo
    {
        static void Main(string[] args)
        {
            List<int> numbers = Enumerable.Range(1, 12).ToList();
            Console.WriteLine("Splitting a list of 12 numbers into chunks of 5:");
            int[][] chunks = numbers.Chunk(5).ToArray();
            for (int i = 0; i < chunks.Length; i++)
            {
                Console.WriteLine($"Chunk {i + 1}: {string.Join(", ", chunks[i])}");
            }
            Console.WriteLine("Chunking completed successfully.");
        }
    }
}Code language: C# (cs)

Explanation:

  • numbers.Chunk(5): Splits the sequence into consecutive groups of up to 5 elements each, returning a sequence of arrays.
  • The final chunk: Contains whatever elements remain, which may be fewer than 5 if the total count doesn't divide evenly, as seen with the last chunk here containing only 2 numbers.
  • .ToArray(): Converts the sequence of chunks into an array of arrays for easy indexed access.
  • Why this matters: Chunk() is especially useful for batch processing large datasets in manageable, fixed-size groups.

Filed Under: C# Exercises

Did you find this page helpful? Let others know about it. Sharing helps me continue to create free Python resources.

TweetF  sharein  shareP  Pin

About Vishal

I’m Vishal Hule, the Founder of PYnative.com. As a Python developer, I enjoy assisting students, developers, and learners. Follow me on Twitter.

Related Tutorial Topics:

C# Exercises

All Coding Exercises:

C Exercises
C++ Exercises
Python Exercises
Java Exercises
C# Exercises

Python Exercises and Quizzes

Free coding exercises and quizzes cover Python basics, data structure, data analytics, and more.

  • 15+ Topic-specific Exercises and Quizzes
  • Each Exercise contains 25+ questions
  • Each Quiz contains 25 MCQ
Exercises
Quizzes

Leave a Reply Cancel reply

your email address will NOT be published. all comments are moderated according to our comment policy.

Use <pre> tag for posting code. E.g. <pre> Your entire code </pre>

In: C# Exercises
TweetF  sharein  shareP  Pin

  C# Exercises

  • C# Exercise for Beginners
  • C# Loops Exercise
  • C# Array Exercise
  • C# String Exercise
  • C# OOP Exercise
  • C# Structs, Records and Enums Exercise
  • C# Collections Exercise
  • C# List Exercise
  • C# Dictionary Exercise
  • C# LINQ Exercise
  • C# Exception Handling Exercise
  • C# File Handling Exercise
  • C# Date and Time Exercise
  • C# Generics Exercise
  • C# Lambda Expressions Exercise
  • C# Delegates and Events Exercise
  • C# Extension Methods Exercise
  • C# Regex Exercise
  • C# Pattern Matching Exercise
  • C# Iterators and Yield Exercise
  • C# Indexers and Operator Overloading Exercise
  • C# Random Data Generation Exercise

All Coding Exercises

Python Exercises C Exercises C++ Exercises Java Exercises C# Exercises

About PYnative

PYnative.com is for Python lovers. Here, You can get Tutorials, Exercises, and Quizzes to practice and improve your Python skills.

Follow Us

To get New Python Tutorials, Exercises, and Quizzes

  • Twitter
  • Facebook
  • Sitemap

Explore Python

  • Learn Python
  • Python Basics
  • Python Databases
  • Python Exercises
  • Python Quizzes
  • Online Python Code Editor
  • Python Tricks

Coding Exercises

  • C Exercises
  • C++ Exercises
  • Python Exercises
  • Java Exercises
  • C# Exercises

Legal Stuff

  • About Us
  • Contact Us

We use cookies to improve your experience. While using PYnative, you agree to have read and accepted our:

  • Terms Of Use
  • Privacy Policy
  • Cookie Policy

Copyright © 2018–2026 pynative.com