New LINQ Methods in .NET 9: Index, CountBy, and AggregateBy

In this article, I will explore the new LINQ methods Index, CountBy, and AggregateBy introduced in .NET 9. These powerful features are designed to enhance LINQ's functionality and flexibility, making it even more valuable for developers. By using these methods, you can simplify complex data tasks, write cleaner and more efficient code, and improve your overall development experience.

.NET 9 LINQ Enhancements

.NET 9 LINQ enhancements

Let's dive into each method with in-depth explanations and practical code examples. We will explore how Index, CountBy, and AggregateBy can improve your coding experience and simplify data manipulation tasks in .NET 9.

Create a Console Application using the .NET 9 Framework.

Configure .NET 9 Project

Select Framework .Net 9

Note. Let's go through each method one by one, in detail, with code snippets and examples.

Index

  • The Index<T> method in LINQ, introduced with .NET 9, offers a way to traverse a collection while simultaneously obtaining the index and value of each element. This is particularly beneficial when both the position and value of an element are required during iteration, a task that was less intuitive before this method became available.

Syntax

IEnumerable<(int Index, T Value)> Index<T>(this IEnumerable<T> source);

How does the index method Work?

For each element in the collection, the Index method produces a tuple that includes:

  • The Index of the element in the sequence.
  •  The value of the element itself.

Let's take an example of an employee class with a primary constructor:

public class Employee(int id, string name, string department)
{
    public int Id { get; set; } = id;
    public string Name { get; set; } = name;
    public string Department { get; set; } = department;
}
// Creating a list of employees
List<Employee> employees =
        [
            new Employee(1, "Jignesh Kumar", "HR"),
            new Employee(2, "Chintan patel", "IT"),
            new Employee(3, "Emily Johnson", "Marketing")
        ];

// Using the Index method to get both index and employee data
var _indexedEmployees = employees.Index();

foreach (var (index, employee) in _indexedEmployees)
{
    Console.WriteLine($"Index: {index}, Employee: {employee.Name}, Department: {employee.Department}");
}

Index method .NET 9 output

Real-Time Debugging Using Visual Studio

Output

Index: 0, Employee: Jignesh Kumar, Department: HR
Index: 1, Employee: Chintan patel, Department: IT
Index: 2, Employee: Emily Johnson, Department: Marketing

Key Benefits of Index()

  • Tuple return type: The method provides a tuple containing both the index and value, enabling straightforward access to both during iteration.
  • Simplifies logic: Simplifies use cases where the element's position is required, eliminating the need to manually track an index variable.

Before the introduction of the Index method in .NET 9.

Using Select with Index

LINQ's Select method has an overload that includes an index parameter. Developers often used this to retrieve both the index and value of each element in a collection.

How did developers achieve similar functionality before the Index method in .NET 9?

   List<Employee> employees =
           [
              new Employee(1, "Jignesh Kumar", "HR",50000),
              new Employee(2, "Chintan Patel", "IT",30000),
              new Employee(3, "Emily Johnson", "Marketing",20000)
           ];

var indexedEmployees = employees
    .Select((employee, index) => new { Index = index, employee = employee })
    .ToList();

foreach (var item in indexedEmployees)
{
    Console.WriteLine($"Index: {item.Index}, Name: {item.employee.Name}");
}

CountBy

The CountBy method introduced in .NET 9 is a LINQ extension that streamlines the process of grouping elements by a key and counting the occurrences within each group. By replacing the more complex combination of GroupBy and Select methods, it offers a cleaner, more intuitive approach to writing such queries.

Syntax

IEnumerable<(TKey Key, int Count)> CountBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector
);

How does the CountBy method work?

The method returns an IEnumerable of tuples, where each tuple contains:

  • Key: The key of the group.
  • Count: The number of elements in that group.

Let's add more data to the employee list so we can use the CountBy method effectively on the expanded dataset.

List<Employee> employees =
        [
            new Employee(1, "Jignesh Kumar", "HR"),
            new Employee(2, "Chintan Patel", "IT"),
            new Employee(3, "Emily Johnson", "Marketing"),
            new Employee(3, "Kyle James", "IT"),
            new Employee(3, "Peter Moor", "Marketing"),
            new Employee(3, "Make Patel", "IT"),
        ];

// Apply the CountBy method to the employee list

var departmentCounts = employees.CountBy(emp => emp.Department);

// Loop through and retrieve the count for each department

foreach (var (department, count) in departmentCounts)
{
    Console.WriteLine($"Department: {department}, Employee Count: {count}");
}

CountBy in .Net 9

Real-Time Debugging Using Visual Studio

Output

Department: HR, Employee Count: 1
Department: IT, Employee Count: 3
Department: Marketing, Employee Count: 2

Before the introduction of the CountBy method in .NET 9.

Using GroupBy and Select

To count elements grouped by a specific key (e.g., department in an employee list), you needed to:

  1. Group the elements using GroupBy.
  2. Count the elements in each group using Select.

How did developers achieve similar functionality before the CountBy method in .NET 9?

var departmentCounts = employees
    .GroupBy(emp => emp.Department) // Group employees by department
    .Select(group => new 
    { 
        Department = group.Key, 
        Count = group.Count() // Count employees in each group
    })
    .ToList();

// Output the counts
foreach (var item in departmentCounts)
{
    Console.WriteLine($"Department: {item.Department}, Count: {item.Count}");
}

AggregateBy

The AggregateBy method in .NET 9 is a robust LINQ extension designed to streamline aggregate operations such as summing, averaging, or applying custom calculations on grouped data. It offers a more concise and expressive alternative to using a combination of GroupBy with Select or implementing manual aggregation logic.

Syntax

IEnumerable<(TKey Key, TAccumulate Aggregate)> AggregateBy<TSource, TKey, TAccumulate>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector,
    Func<TAccumulate> seedFactory,
    Func<TAccumulate, TSource, TAccumulate> aggregator
);

How does AggregateBy Work?

  1. Groups the elements based on the key provided by the keySelector.
  2. It uses the seed factory to initialize an accumulator for each group.
  3. Applies the aggregator function to calculate the aggregate value for each group.
 List<Employee> employees =
             [
                 new Employee(1, "Jignesh Kumar", "HR",50000),
                  new Employee(2, "Chintan Patel", "IT",30000),
                  new Employee(3, "Emily Johnson", "Marketing",20000),
                  new Employee(3, "Kyle James", "IT", 50000),
                  new Employee(3, "Peter Moor", "Marketing", 30000),
                  new Employee(3, "Make Patel", "IT",45000),
             ];

 // Apply the CountBy method to the employee list

 var departmentSalaries = employees.AggregateBy(
             emp => emp.Department,                    // Group by Department
             0m,                                // Seed: Start with 0 salary (initialize as decimal)
             (totalSalary, employee) => totalSalary + employee.Salary  // Aggregate: Sum salaries
         ).ToList();

 // Loop through and retrieve the count for each department
 // Output the results
 foreach (var (department, totalSalary) in departmentSalaries)
 {
     Console.WriteLine($"Department: {department}, Total Salary: {totalSalary:C}");
 }

AggregateBy in Linq .net 9

Real-Time Debugging Using Visual Studio

Output

Department: HR, Total Salary:  50,000.00
Department: IT, Total Salary:  1,25,000.00
Department: Marketing, Total Salary:  50,000.00

Before the introduction of the AggregateBy method in .NET 9.

Using GroupBy and Select

To aggregate data for each group, you would:

  1. Use GroupBy to group elements by a specific key.
  2. Use Select to project each group into a key-value pair where the value is computed using an aggregate function.

How did developers achieve similar functionality before the AggregateBy method in .NET 9?

var departmentSalaries = employees
    .GroupBy(emp => emp.Department) 
    .Select(group => new 
    { 
        Department = group.Key, 
        TotalSalary = group.Sum(emp => emp.Salary) 
    })
    .ToList();


foreach (var item in departmentSalaries)
{
    Console.WriteLine($"Department: {item.Department}, Total Salary: {item.TotalSalary}");
}

Summary

In this article, I have demonstrated the power and utility of the new LINQ methods introduced in .NET 9 Index, CountBy, and AggregateBy and how they simplify code while improving readability. I provided examples of how developers handled similar tasks before these methods and highlighted the benefits of the new LINQ features in .NET 9.

If you wish to read more articles, please View My Articles

  1. Implement a retry policy in .NET 6 Applications with Polly
  2. Working with JSON in .NET Core: Newtonsoft.Json, NetJSON, and System.Text.Json
  3. Simplify Your Code with Switch Expressions: Patterns and Examples
  4. Understanding Model Binding in ASP.NET Core with .NET 8
  5. Difference Between =, == And === In JavaScript

Note. I have included my codebase as a zip file, built with Visual Studio 2022 and .NET 9.

Thank you for reading! I hope it was helpful. Please feel free to leave a comment and reach out if you have any questions.


Similar Articles