By Endy Tjahjono. Last update 27 Jul 2017.
I just found out c#’s Enumerable.SelectMany has 4 overloads! I only knew one.
Now figuring out the differences.
Setting up a playing field:
public class Team
{
public string Name { get; set; }
public IEnumerable<string> Members { get; set; }
}
public class MatchResult
{
public Team Team { get; set; }
public int Score { get; set; }
}
And then let’s create a list of match results:
var results = new List<MatchResult>
{
new MatchResult
{
Team = new Team {Name = "Red", Members = new[] {"Wedge", "Luke"}},
Score = 8
},
new MatchResult
{
Team = new Team {Name = "Gold", Members = new[] {"Evaan"}},
Score = 7
}
};
Now if I want to get a list of team member with their team score, previously I would do it like this:
var memberScores = results.SelectMany(
r => r.Team.Members.Select(m => new { Member = m, Score = r.Score })).
ToList();
And I would get:
[
{ Member = "Wedge", Score = 8 },
{ Member = "Luke", Score = 8 },
{ Member = "Evaan", Score = 7 }
]
But it turned out there is another way to do it:
var memberScores = results.
SelectMany(
result => result.Team.Members,
(result, member) => new { Member = member, Score = result.Score }).
ToList();
Which is easier to read I think.
The other two overloads are just to add item index if you need it:
var memberScores = results.SelectMany(
(r, idx) => r.Team.Members.Select(m => new { Member = m, Score = r.Score })).
ToList();
And
var memberScores = results.
SelectMany(
(result, idx) => result.Team.Members,
(result, member) => new { Member = member, Score = result.Score }).
ToList();