Flatten Nested Collections with SelectMany in C#Flatten Nested Collections with SelectMany in C#

Flatten Nested Collections with SelectMany in C#

When dealing with nested collections in C#, the SelectMany method is a powerful tool for efficiently flattening these collections. Suppose you have a list of departments, where each department contains a list of employees. Using SelectMany in C# allows you to easily combine all employees into a single, flat list. This method simplifies the task of handling nested data and significantly enhances code readability.

Problem Overview

Imagine you have a list of departments where each department contains a list of employees:

public class Employee
{
public string Name { get; set; }
}

public class Department
{
public List Employees { get; set; }
}

List departments = new List
{
new Department
{
Employees = new List
{
new Employee { Name = "Alice" },
new Employee { Name = "Bob" }
}
},
new Department
{
Employees = new List
{
new Employee { Name = "Charlie" },
new Employee { Name = "David" }
}
}
};

Here, departments is a list where each item is a Department object with a list of Employee objects. The challenge is to extract a single list of all employees from these nested collections.

Traditional Approach: Nested Loops

Without SelectMany, you might use nested loops to flatten this structure:

List<Employee> allEmployees = new List<Employee>();

foreach (var department in departments)
{
foreach (var employee in department.Employees)
{
allEmployees.Add(employee);
}
}

 

This approach works but can become cumbersome and harder to read, especially as the complexity of your data structures increases.

Using SelectMany in C#

The SelectMany method provides a more elegant and readable way to achieve the same result. It flattens the nested collections into a single collection with a single line of code:

List<Employee> allEmployees = departments
.SelectMany(department => department.Employees)
.ToList();

Here’s how SelectMany works:

  • SelectMany takes a collection of Department objects and applies a transformation function to each department.
  • The transformation function (department => department.Employees) extracts the Employees list for each department.
  • SelectMany then flattens all these Employee lists into a single IEnumerable<Employee>.
  • Finally, ToList() converts the result into a List<Employee>.

This approach not only simplifies your code but also improves its performance by leveraging LINQ’s internal optimizations.

Advanced Use Case: Filtering and Sorting

SelectMany can also be combined with other LINQ methods for more advanced queries. For instance, if you want to filter and sort employees by name, you can do it like this:

List<Employee> sortedEmployees = departments
.SelectMany(department => department.Employees)
.Where(employee => employee.Name.StartsWith("A"))
.OrderBy(employee => employee.Name)
.ToList();

 

In this example, SelectMany flattens the employee lists, Where filters employees whose names start with “A”, and OrderBy sorts them alphabetically.

Advantages of Using SelectMany in C#

  1. Readability: Using SelectMany in C# makes your code much more readable compared to traditional nested loops.
  2. Maintainability: LINQ methods like SelectMany are easier to maintain and less error-prone, reducing the likelihood of bugs.
  3. Performance: SelectMany often provides performance benefits through internal optimizations and efficient handling of large data sets.

Conclusion

In summary, SelectMany in C# is a powerful and efficient method for flattening nested collections. By integrating SelectMany into your LINQ queries, you can simplify your code, making it more readable and maintainable. Whether you’re handling basic data structures or complex nested collections, SelectMany offers a robust solution for effective data manipulation. Embrace SelectMany to handle complex data structures with ease and enhance your coding practices.

Another example

Read also about SelectMany in C#

Learn .NET