Difference Between Select and SelectMany
SelectMany
flattens queries that return lists of lists. For example
public class PhoneNumber
{
public string Number { get; set; }
}
public class Person
{
public IEnumerable<PhoneNumber> PhoneNumbers { get; set; }
public string Name { get; set; }
}
IEnumerable<Person> people = new List<Person>();
// Select gets a list of lists of phone numbers
IEnumerable<IEnumerable<PhoneNumber>> phoneLists = people.Select(p => p.PhoneNumbers);
// SelectMany flattens it to just a list of phone numbers.
IEnumerable<PhoneNumber> phoneNumbers = people.SelectMany(p => p.PhoneNumbers);
// And to include data from the parent in the result:
// pass an expression to the second parameter (resultSelector) in the overload:
var directory = people
.SelectMany(p => p.PhoneNumbers,
(parent, child) => new { parent.Name, child.Number });
Live Demo on .NET Fiddle
SelectMany()
lets you collapse a multidimensional sequence in a way that would otherwise require a second Select()
or loop.
More details at this blog post.
Select many is like cross join operation in SQL where it takes the cross product.
For example if we have
Set A={a,b,c}
Set B={x,y}
Select many can be used to get the following set
{ (x,a) , (x,b) , (x,c) , (y,a) , (y,b) , (y,c) }
Note that here we take the all the possible combinations that can be made from the elements of set A and set B.
Here is a LINQ example you can try
List<string> animals = new List<string>() { "cat", "dog", "donkey" };
List<int> number = new List<int>() { 10, 20 };
var mix = number.SelectMany(num => animals, (n, a) => new { n, a });
the mix will have following elements in flat structure like
{(10,cat), (10,dog), (10,donkey), (20,cat), (20,dog), (20,donkey)}
var players = db.SoccerTeams.Where(c => c.Country == "Spain")
.SelectMany(c => c.players);
foreach(var player in players)
{
Console.WriteLine(player.LastName);
}
- De Gea
- Alba
- Costa
- Villa
- Busquets
...