Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing nested loop with Linq

Tags:

c#

linq

In the query below I do calculate the combined value of all football teams within league 1. The solution I've came up with, though it works, seems rather bulky.

I would like to find a better approach i.e. a one lined linq query like so:

footballteams.Where(x => x.League == 1).Sum(x => x.Networth);

My current code:

List<IGrouping<int, FootballTeam>> footballTeams = context.FootballTeam
    .GetQueryable()
    .GroupBy(x => x.TeamName)
    .ToList();

var prem = footballTeams.Where(x => x.League == 1).ToList();
var totalWealth = 0;

foreach (var team in prem)
{
    foreach(var singleteam in team)
    {
         totalWealth = totalWealth + singleteam.networth;
    }
}
like image 767
J.Doe Avatar asked Jun 05 '18 21:06

J.Doe


3 Answers

Use SelectMany then Sum.

var totalWealth = footballTeams.Where(x => x.League == 1)
                               .SelectMany(x => x.Select(e => e.networth))
                               .Sum();

SelectMany() Exceprt:

Projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence.

like image 140
Ousmane D. Avatar answered Oct 22 '22 04:10

Ousmane D.


You can do it all in a single statement:

var totalWorth = context.FootballTeam
    .GetQueryable()
    .Where(x => x.League == 1)
    .GroupBy(x => x.TeamName)
    .Sum(x => x.Sum(y => y.NetWorth));

You also skip the enumeration performed by the two ToList() calls with this.

like image 41
Camilo Terevinto Avatar answered Oct 22 '22 06:10

Camilo Terevinto


totalWealth = footballTeams
    .Where(x => x.League == 1)
    .Select(
        x => x.Select(
            y => y.networth
        ).Sum()
    )
    .Sum();

If you want you can make it one line, but you will notice that readability is crucial for productive coding.

like image 4
Tobias Brohl Avatar answered Oct 22 '22 05:10

Tobias Brohl