ZetCode

C# LINQ SelectMany

last modified October 16, 2026

In this article we show how to flatten sequences into a single sequence with the LINQ SelectMany method.

Language-Integrated Query (LINQ) is a domain-specific language for querying data from various data sources, including arrays, lists, XML files, or databases.

The SelectMany method projects each element of a sequence to a sequence and flattens the resulting sequences into one sequence. While Select produces one output element for each input element, SelectMany can produce zero, one, or many.

C# LINQ SelectMany array of arrays

The first example is a simple program which uses the SelectMany method.

Program.cs
int[][] vals =
[
    [1, 2, 3],
    [4],
    [5, 6, 6, 2, 7, 8]
];

var res = vals.SelectMany(a => a).OrderBy(e => e);
Console.WriteLine(string.Join(", ", res));

In the program, we have a jagged array. With the SelectMany method, we flatten it into a single sequence of values. The values are also ordered.

$ dotnet run
1, 2, 2, 3, 4, 5, 6, 6, 7, 8

C# LINQ SelectMany Distinct

The Distinct method is used to get unique values.

Program.cs
List<List<int>> vals =
[
    [1, 2, 3, 3],
    [4],
    [5, 6, 6, 7, 7]
];

var res = vals.SelectMany(list => list)
              .Distinct()
              .OrderByDescending(e => e);

Console.WriteLine(string.Join(", ", res));

In the program, we flatten all integers from a list of lists into a single sequence. We pick up only unique values and order them in descending order.

$ dotnet run
7, 6, 5, 4, 3, 2, 1

C# LINQ SelectMany string list

A string is a sequence of characters. In the next example, we apply the SelectMany method on a list of strings.

Program.cs
List<string> words = ["осторожность", "собака", "облако", "чашка"];

var letters = words.SelectMany(e => e);
Console.WriteLine(string.Join(",", letters));

var unique = words.SelectMany(e => e).Distinct().Order();
Console.WriteLine(string.Join("", unique));

We define a list of Russian words. The SelectMany method cuts the words into letters and forms a single sequence from them. In the second query, we get the unique letters in alphabetical order.

$ dotnet run
о,с,т,о,р,о,ж,н,о,с,т,ь,с,о,б,а,к,а,о,б,л,а,к,о,ч,а,ш,к,а
абжклнорстчшь

C# LINQ SelectMany on record property

The next example applies the SelectMany method on a property of records.

Program.cs
List<User> users =
[
    new("John", "Doe", ["red", "blue"]),
    new("Roger", "Roe", ["black", "yellow"]),
    new("Jerry", "Dane", ["blue", "orange", "white"]),
    new("Thomas", "Green", ["brown"])
];

List<string> res = users.SelectMany(e => e.Colours).ToList();
Console.WriteLine(string.Join(",", res));

record User(string FirstName, string LastName, List<string> Colours);

We have a list of users, who have their favourite colours specified. The colours are defined as a list of strings inside a record type.

List<string> res = users.SelectMany(e => e.Colours).ToList();

The flattening operation is applied on the Colours property of the records.

$ dotnet run
red,blue,black,yellow,blue,orange,white,brown

C# LINQ SelectMany with result selector

An overload of SelectMany takes a second function, the result selector. It receives both the parent element and the inner element, so we do not lose the information about where each inner element came from.

Program.cs
List<User> users =
[
    new("John", "Doe", ["red", "blue"]),
    new("Roger", "Roe", ["black", "yellow"]),
    new("Jerry", "Dane", ["blue", "orange", "white"])
];

var pairs = users.SelectMany(u => u.Colours,
    (u, colour) => $"{u.FirstName} likes {colour}");

foreach (var pair in pairs)
{
    Console.WriteLine(pair);
}

record User(string FirstName, string LastName, List<string> Colours);

For each colour, we create a string that also contains the name of the user.

$ dotnet run
John likes red
John likes blue
Roger likes black
Roger likes yellow
Jerry likes blue
Jerry likes orange
Jerry likes white

C# LINQ SelectMany query syntax

In the query syntax, SelectMany corresponds to two from clauses.

Program.cs
List<User> users =
[
    new("John", "Doe", ["red", "blue"]),
    new("Roger", "Roe", ["black", "yellow"]),
    new("Jerry", "Dane", ["blue", "orange", "white"])
];

var res = from u in users
          from colour in u.Colours
          where colour == "blue"
          select u.FirstName;

Console.WriteLine(string.Join(", ", res));

char[] letters = ['a', 'b', 'c'];
int[] digits = [1, 2];

var product = from l in letters
              from d in digits
              select $"{l}{d}";

Console.WriteLine(string.Join(" ", product));

record User(string FirstName, string LastName, List<string> Colours);

In the first query, we find the users who like blue colour. The second query creates a Cartesian product of letters and digits; the inner sequence does not have to depend on the outer element.

$ dotnet run
John, Jerry
a1 a2 b1 b2 c1 c2

C# LINQ Select vs SelectMany

If we use Select instead of SelectMany, we get a sequence of lists, which we have to flatten ourselves.

Program.cs
List<User> users =
[
    new("John", "Doe", ["red", "blue"]),
    new("Roger", "Roe", ["black", "yellow"]),
    new("Jerry", "Dane", ["blue", "orange", "white"]),
    new("Thomas", "Green", ["brown"])
];

IEnumerable<List<string>> res = users.Select(e => e.Colours);

var colours = new List<string>();

foreach (var cols in res)
{
    colours.AddRange(cols);
}

Console.WriteLine(string.Join(",", colours));

record User(string FirstName, string LastName, List<string> Colours);

The Select method returns an IEnumerable<List<string>>. We go over the lists and add their elements to a single list with AddRange. The SelectMany method does the same in one call.

$ dotnet run
red,blue,black,yellow,blue,orange,white,brown

Source

Enumerable.SelectMany method

In this article we have presented the LINQ SelectMany method.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all C# tutorials.