Enumerable.Select
returns an output element for every input element.
Whereas Enumerable.SelectMany
produces a variable number of output elements for each input element. This means that the output sequence may contain more or fewer elements than were in the input sequence.
Lambda expressions
passed to Enumerable.Select
must return a single item. Lambda expressions passed to Enumerable.SelectMany
must produce a child sequence. This child sequence may contain a varying number of elements for each element in the input sequence.
Example
class Invoice
{
public int Id { get; set; }
}
class Customer
{
public Invoice[] Invoices {get;set;}
}
var customers = new[] {
new Customer {
Invoices = new[] {
new Invoice {Id=1},
new Invoice {Id=2},
}
},
new Customer {
Invoices = new[] {
new Invoice {Id=3},
new Invoice {Id=4},
}
},
new Customer {
Invoices = new[] {
new Invoice {Id=5},
new Invoice {Id=6},
}
}
};
var allInvoicesFromAllCustomers = customers.SelectMany(c => c.Invoices);
Console.WriteLine(
string.Join(",", allInvoicesFromAllCustomers.Select(i => i.Id).ToArray()));
Output:
1,2,3,4,5,6
Enumerable.SelectMany
can also be achieved with a syntax-based query using two consecutive from
clauses:
var allInvoicesFromAllCustomers
= from customer in customers
from invoice in customer.Invoices
select invoice;