I'd like to know how to use SelectMany()
. It seems to take so many arguments and from my own research I noticed that SelectMany()
might be the 'father' of all other select operations.

- 3,425
- 30
- 38
- 48

- 5,278
- 6
- 41
- 66
6 Answers
Select many allows you to select a property from your query source that is an IEnumerable<T> collection, but instead of returning a collection of collections (IEnumerable<IEnumerable<T>>) it will flatten the collections into a single collection.
Here's an example that you can run to demonstrate the differences between Select and SelectMany:
//set up some data for our example
var tuple1 = new { Name = "Tuple1", Values = new int [] { 1, 2, 3 } };
var tuple2 = new { Name = "Tuple2", Values = new int [] { 4, 5, 6 } };
var tuple3 = new { Name = "Tuple3", Values = new int [] { 7, 8, 9 } };
//put the tuples into a collection
var tuples = new [] { tuple1, tuple2, tuple3 };
//"tupleValues" is an IEnumerable<IEnumerable<int>> that contains { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }
var tupleValues = tuples.Select(t => t.Values);
//"tupleSelectManyValues" is an IEnumerable<int> that contains { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
var tupleSelectManyValues = tuples.SelectMany(t => t.Values);
By using SelectMany you make it easier to query values within child collections.

- 7,431
- 18
- 59
- 84

- 21,196
- 13
- 77
- 99
-
Thanks abatishchev, I hadn't spotted the typo. – Doctor Jones Nov 26 '10 at 10:10
There are several overloads to SelectMany
. One of them allows you to keep track of any relationship between parent and children while traversing the hierarchy.
Example: suppose you have the following structure: League -> Teams -> Player
You can easily return a flat collection of players. However you may loose any reference to the team a player is part of.
Fortunately there is an overload for such purpose:
var teamsAndTheirLeagues =
from helper in leagues.SelectMany
( l => l.Teams
, ( league, team ) => new { league, team } )
where helper.team.Players.Count > 2
&& helper.league.Teams.Count < 10
select new
{ LeagueID = helper.league.ID
, Team = helper.team
};
The previous example is taken from Dan's IK blog:
http://blogs.interknowlogy.com/2008/10/10/use-linqs-selectmany-method-to-flatten-collections/
I strongly recommend you take a look at it.

- 7,695
- 6
- 46
- 61
-
"*One of them allows you to keep track of any relationship between parent and children*" actually two out of the [four methods](https://learn.microsoft.com/en-us/dotnet/api/system.linq.queryable.selectmany). And two of the four in addition give access to the index of the parent in its own collection. – mins May 14 '20 at 15:26
SelectMany basically flattens and processes hierarchical data, and has two main forms
(for the purposes of examples, see this initial code)
class TestObj
{
public string Name { get; set; }
public List<string> Items { get; set; }
}
var hierarchicalCollection = new List<TestObj>();
hierarchicalCollection.Add(new TestObj()
{Items = new List<string>()
{"testObj1-Item1", "testObj1-Item2"}, Name="t1"});
hierarchicalCollection.Add(new TestObj()
{Items = new List<string>()
{"testObj2-Item1", "testObj2-Item2"}, Name="t2"});
option 1) creates a collection from a collection of collections (essentially flattening hierarchical data)
IEnumerable<string> flattenedCollection =
hierarchicalCollection.SelectMany(t => t.Items);
The result is:
"testObj1-Item1"
"testObj1-Item2"
"testObj2-Item1"
"testObj2-Item2"
option 2) creates a collection from a collection of collections, and then processes each item of the new collection via a reference to the original parent
IEnumerable<string> flattenedModifiedCollection =
hierarchicalCollection.SelectMany
(t => t.Items, (t, i) => t.Name + " : " + i);
the result is:
"t1 : testObj1-Item1"
"t1 : testObj1-Item2"
"t2 : testObj2-Item1"
"t2 : testObj2-Item2"
each of the above useages has a variant, where the index of the item being processed is available to the transformation functions.

- 20,076
- 6
- 59
- 90
I use this extension all the time for diving into hierarchies.
Another cool way to do this when the Extensions get a bit messy is to use the formal LINQ way, like:
var vehicles = from cust in context.Customers
from fleet in cust.Fleets
from v in fleet.Vehicles
select v;
This would be the equivalent of:
var vehicles = context.Customers.SelectMany(c => c.Fleets).SelectMany(f => f.Vehicles);
This can get a bit long winded when adding in where clauses and joins etc. Hope this helps!

- 3,354
- 1
- 22
- 25
Here is another (VB.NET) usage example:
'Original list
Dim l() As String = {"/d", "/bc:\Temp\In*;c:\Temp\Out", "/hABC", "/s123"}
'Processed list: will list first 2 characters from each string member.
Dim L1 As IEnumerable(Of String) = l.SelectMany(Function(x As String) {x.Substring(0, 2)})
Dim L2 As List(Of String) = l.SelectMany(Function(x As String) {x.Substring(0, 2)}).ToList
'Will return dictionary like list with keys==2 characters and values the rest from each string member.
Dim L3 As List(Of KeyValuePair(Of String, String)) = l.SelectMany(Function(x As String) {New KeyValuePair(Of String, String)(x.Substring(0, 2), x.Substring(2))}).ToList

- 2,707
- 5
- 31
- 36

- 992
- 10
- 13
I have had some fun using SelectMany in LINQ. The following link described returning an IEnumerable in a LINQ select clause, which returns a sequence of sequences, and using SelectMany to flatten that into a simple sequence. "Linq to XML using Let, Yield return and Selectmany". It is not just a SelectMany use case, but part of an approach which generates multiple outputs from a single input in LINQ.

- 772
- 4
- 5