SelectMany
Summary
Projects each element of a sequence to an enumerable sequence and flattens the resulting sequences into one sequence.
There are multiple overloads for SelectMany
, allowing for different ways to project and combine elements. The core idea is to transform each element of an input sequence into zero or more elements in an output sequence.
Remarks
The SelectMany
method is a fundamental operator in LINQ. It is often used to flatten nested collections or to perform a one-to-many projection.
When using the overload that takes two selector functions, the collectionSelector
determines the collection to flatten for each source element, and the resultSelector
determines how to combine the source element with an element from the flattened collection to produce the final result.
It's important to note the difference between Select
and SelectMany
. Select
transforms each element into a single new element, while SelectMany
transforms each element into a sequence of new elements and then concatenates these sequences.
Returns
An IEnumerable<TResult>
whose elements are the result of invoking the transform (one) or join (two) functions on each element of the source sequence.
Parameters
Name | Type | Description |
---|---|---|
source |
IEnumerable<TSource> |
An IEnumerable<T> to project and flatten. |
selector |
Func<TSource, IEnumerable<TResult>> or Func<TSource, int, IEnumerable<TResult>> |
A transform function to apply to each element of the source sequence. The second form also includes the index of the source element. |
collectionSelector |
Func<TSource, IEnumerable<TCollection>> or Func<TSource, int, IEnumerable<TCollection>> |
A transform function to apply to each element of the source sequence to produce a collection of values. The second form also includes the index of the source element. |
resultSelector |
Func<TSource, TCollection, TResult> |
A transform function to combine a source element with an element from the collection produced by the collectionSelector . |
Exceptions
ArgumentNullException
:source
orselector
is null.
Example
Example 1: Flattening a list of lists
This example demonstrates how to use SelectMany
to flatten a list of lists into a single list.
using System;
using System.Collections.Generic;
using System.Linq;
public class Example
{
public static void Main(string[] args)
{
List<List<int>> listOfLists = new List<List<int>>
{
new List<int> { 1, 2, 3 },
new List<int> { 4, 5 },
new List<int> { 6, 7, 8, 9 }
};
// Using SelectMany to flatten the list of lists
IEnumerable<int> flattenedList = listOfLists.SelectMany(innerList => innerList);
Console.WriteLine("Flattened list:");
foreach (int item in flattenedList)
{
Console.Write(item + " ");
}
// Output: Flattened list: 1 2 3 4 5 6 7 8 9
}
}
Example 2: Using SelectMany with resultSelector
This example shows how to use the overload of SelectMany
that takes a resultSelector
to create a new sequence of strings by combining elements from two sequences.
using System;
using System.Collections.Generic;
using System.Linq;
public class Example
{
public static void Main(string[] args)
{
List<string> fruits = new List<string> { "apple", "banana", "cherry" };
List<string> colors = new List<string> { "red", "yellow", "purple" };
// Using SelectMany with a resultSelector to combine fruits and colors
IEnumerable<string> fruitColors = fruits.SelectMany(
fruit => colors, // collectionSelector: for each fruit, iterate through colors
(fruit, color) => $"{color} {fruit}" // resultSelector: combine fruit and color
);
Console.WriteLine("Combined fruit and color strings:");
foreach (string item in fruitColors)
{
Console.WriteLine(item);
}
// Output:
// red apple
// yellow apple
// purple apple
// red banana
// yellow banana
// purple banana
// red cherry
// yellow cherry
// purple cherry
}
}