C# LINQ SelectMany
last modified July 5, 2023
In this article we show how to flatten sequences into a single sequence with
LINQ's 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 flattens a number of sequences into a single
sequence.
C# LINQ SelectMany array of arrays
The first example is a simple program which uses LINQ SelectMany
method.
int[][] vals = { new[] {1, 2, 3}, new[] {4}, new[] {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 an array of arrays. With the SelectMany
method, we flatten the two-dimensional array into an one-dimensional array
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.
var vals = new List<List<int>> { new List<int> {1, 2, 3, 3}, new List<int> {4}, new List<int> {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
In the next example, we apply the SelectMany
method on a list of
strings.
var ru_words = new List<string> { "осторожность", "собака", "облако", "чашка" }; var res = ru_words.SelectMany(e => e); Console.WriteLine(string.Join(",", res));
We define a list of Russian words. The SelectMany
cuts the words
into letters and forms a single sequence from them.
$ dotnet run о,с,т,о,р,о,ж,н,о,с,т,ь,с,о,б,а,к,а,о,б,л,а,к,о,ч,а,ш,к,а
C# LINQ SelectMany on record field
The next example applies the SelectMany
method on a record field.
var users = new List<User> { new ("John", "Doe", new List<string> { "red", "blue" }), new ("Roger", "Roe", new List<string> { "black", "yellow" }), new ("Jerry", "Dane", new List<string> { "blue", "orange", "white" }), new ("Thomas", "Green", new List<string> { "brown" }), }; List<string> res = users.SelectMany(e => e.colours).ToList(); Console.WriteLine(string.Join(",", res)); record User(string fname, string lname, 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
fields of the
records.
$ dotnet run red,blue,black,yellow,blue,orange,white,brown
C# LINQ Select
We can perform the same operations with Select
; the
SelectMany
is more convenient.
var users = new List<User> { new ("John", "Doe", new List<string> { "red", "blue" }), new ("Roger", "Roe", new List<string> { "black", "yellow" }), new ("Jerry", "Dane", new List<string> { "blue", "orange", "white" }), new ("Thomas", "Green", new List<string> { "brown" }), }; IEnumerable<List<string>> res = users.Select(e => e.colours).ToList(); List<string> colours = new List<string>(); foreach(var cols in res) { foreach (var col in cols) { colours.Add(col); } } Console.WriteLine(string.Join(",", colours)); colours.Clear(); foreach (var data in res) { colours.AddRange(data); } Console.WriteLine(string.Join(",", colours)); record User(string fname, string lname, List<string> colours);
In the example we flatten all favourite colours into a list of strings.
foreach(var cols in res) { foreach (var col in cols) { colours.Add(col); } }
In the first case, we use two foreach loops.
foreach (var data in res) { colours.AddRange(data); }
In the second case, we use a foreach loop and the AddRange
method.
$ dotnet run red,blue,black,yellow,blue,orange,white,brown red,blue,black,yellow,blue,orange,white,brown
Source
In this article we have presented the LINQ SelectMany
method.
Author
List all C# tutorials.