How to Use SelectMany in LINQ - C#

This is a quick guide on how to use the SelectMany LINQ operator.

The SelectMany command allows us to map each element of a sequence into an IEnumerable and flattens them into a single sequence.

Let’s take a look at an example with two simple object collections:

class UsingLinq 
{
    public static void Main (string[] args) 
    {
        var people = new List<Person>() 
        { 
            new Person() { PersonId = 1, Name = "Belinda", Age = 70 },
            new Person() { PersonId = 2, Name = "Betty",  Age = 81 },
            new Person() { PersonId = 3, Name = "Will",  Age = 18 },
            new Person() { PersonId = 4, Name = "Andy", Age = 70 },
            new Person() { PersonId = 5, Name = "Rob", Age = 15 }
        };

		var morePeople = new List<Person>() 
        { 
            new Person() { PersonId = 6, Name = "Walter", Age = 50 },
            new Person() { PersonId = 7, Name = "Wendy",  Age = 81 },
            new Person() { PersonId = 8, Name = "Agatha",  Age = 64 },
        };

		var everyone = new List<List<Person>>() { people, morePeople };
	}
}

class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

    public Person() {}

    public void Introduce() 
    {
        Console.WriteLine($"My name is {Name}, and I am {Age} years old.");
    }
}

Using the method syntax, let’s use SelectMany to return both people lists as a single IEnumerable:

public static void Main (string[] args) 
{
	var people = new List<Person>() 
	{ 
		new Person() { PersonId = 1, Name = "Belinda", Age = 70 },
		new Person() { PersonId = 2, Name = "Betty",  Age = 81 },
		new Person() { PersonId = 3, Name = "Will",  Age = 18 },
		new Person() { PersonId = 4, Name = "Andy", Age = 70 },
		new Person() { PersonId = 5, Name = "Rob", Age = 15 }
	};

	var morePeople = new List<Person>() 
	{ 
		new Person() { PersonId = 6, Name = "Walter", Age = 50 },
		new Person() { PersonId = 7, Name = "Wendy",  Age = 81 },
		new Person() { PersonId = 8, Name = "Agatha",  Age = 64 },
	};

	var everyone = new List<List<Person>>() { people, morePeople };

	var allNames = everyone
		.SelectMany(p => p)
		.Select(p => p.Name);
 
	foreach(String name in allNames)
	{
		Console.WriteLine(name);
	}
}

This will give us the following output:

Belinda
Betty
Will
Andy
Rob
Walter
Wendy
Agatha

Real-World Example: Flattening Nested Collections

SelectMany really shines when you need to flatten a property that is itself a collection. Here each Person has a list of hobbies, and we want every unique hobby across all people:

var people = new List<Person>()
{
    new Person() { Name = "Belinda", Hobbies = new List<string> { "Cooking", "Reading" } },
    new Person() { Name = "Will", Hobbies = new List<string> { "Gaming", "Cooking" } }
};

var allHobbies = people.SelectMany(p => p.Hobbies).Distinct();

foreach(var hobby in allHobbies)
{
    Console.WriteLine(hobby);
}

Output:

Cooking
Reading
Gaming

Select vs SelectMany

Select maps each element to exactly one output element — you always get the same number of items back. SelectMany maps each element to a collection and then flattens all of those collections into a single sequence.

Use Select when you want a 1-to-1 transformation. Use SelectMany when each source element contains (or produces) multiple items and you want them all in one flat list.

For a deeper look at Select, see How to Use Select in LINQ.