What is the difference between `Select()` and `SelectMany()`?
4 minintermediate.NETLINQprojection
Quick Answer
`Select()` performs a one-to-one projection, transforming each element and returning `IEnumerable<TResult>`. `SelectMany()` performs a one-to-many projection: it maps each element to a sequence and then flattens all those sequences into a single sequence. Use `Select` to reshape elements and `SelectMany` to flatten nested collections (e.g., all order lines across all orders).
Detailed Answer
Select()
- Projects each element into a new form (1-to-1 transformation)
- Returns
IEnumerable<T> - Maintains the structure of the collection
SelectMany()
- Flattens nested collections into a single sequence (1-to-many transformation)
- Returns flattened
IEnumerable<T> - Useful for hierarchical or nested data
// Sample data
var schools = new List
{
new School
{
Name = "Lincoln High",
Students = new[] { "Alice", "Bob" }
},
new School
{
Name = "Jefferson High",
Students = new[] { "Charlie", "Diana" }
}
};
// Select() - Returns IEnumerable
var selectResult = schools.Select(s => s.Students);
// Result: [ ["Alice", "Bob"], ["Charlie", "Diana"] ]
// You get a collection of collections
// SelectMany() - Returns IEnumerable
var selectManyResult = schools.SelectMany(s => s.Students);
// Result: ["Alice", "Bob", "Charlie", "Diana"]
// You get a flattened single collection
// Another example
var numbers = new List<List>
{
new List { 1, 2, 3 },
new List { 4, 5, 6 },
new List { 7, 8, 9 }
};
// Select - nested structure preserved
var selected = numbers.Select(list => list);
// Type: IEnumerable<List>
// SelectMany - flattened
var flattened = numbers.SelectMany(list => list);
// Type: IEnumerable
// Result: [1, 2, 3, 4, 5, 6, 7, 8, 9]
// Practical example: Get all words from sentences
var sentences = new[] { "Hello world", "LINQ is powerful" };
var allWords = sentences.SelectMany(s => s.Split(' '));
// Result: ["Hello", "world", "LINQ", "is", "powerful"]