SelectMany

public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector)
public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TResult>> selector)
public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, int, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)

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 or selector 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
    }
}