Difference Between Select and SelectMany in LINQ

By FoxLearn 12/12/2024 1:08:46 AM   39
In LINQ, Select and SelectMany are both used to project elements from a collection, but they behave differently, especially when dealing with nested collections or sequences.

Use Select when you want to project elements to a different shape, but don't need to flatten nested collections.

For example, Using Select

var numbers = new List<int> { 1, 2, 3, 4, 5 };
var squaredNumbers = numbers.Select(x => x * x).ToList();
Console.WriteLine(string.Join(", ", squaredNumbers));  // Output: 1, 4, 9, 16, 25

The result is one element for each element in the original collection, and the result is typically a collection of transformed elements.

In this example, each number is squared, and the result is a collection of the squared values.

Use SelectMany when you need to flatten sequences or handle collections inside collections.

For example, Using SelectMany

var numbers = new List<int> { 1, 2, 3 };
var nestedList = numbers.SelectMany(x => new List<int> { x, x * 2 }).ToList();
Console.WriteLine(string.Join(", ", nestedList));  // Output: 1, 2, 2, 4, 3, 6

The result is a flattened sequence from the inner collections (or sequences) produced by the selector.

In this example, SelectMany flattens the resulting nested sequences ({1, 2}, {2, 4}, {3, 6}) into a single, flattened list of numbers.

The SelectMany() method is used to flatten a sequence where each element is a collection or sequence itself.

internal class User
{
    public string UserName { get; set; }
    public List<string> Roles { get; set; }
}

For example:

internal class Program
{
    static void Main(string[] args)
    {
        var users = new List<User>
            {
                new User { UserName = "Reza" , Roles = new List<string>{ "Admin" } },
                new User { UserName = "Amin" , Roles = new List<string>{ "Guest", "Reseption" } },
                new User { UserName = "Nima" , Roles = new List<string>{ "Guest" } },
            };
        var query = users.SelectMany(user => user.Roles, (user, role) => new { user.UserName, role });
        foreach (var obj in query)
            Console.WriteLine(obj);
    }
}

Output:

{ UserName = Lucy, role = Admin }
{ UserName = Amin, role = Guest }
{ UserName = Amin, role = Reseption }
{ UserName = Nima, role = Guest }