HappySylveon
HappySylveon

Reputation: 73

C# - LINQ Query for this purpose

I have the following classes with these fields

public class Account {
     public int Id { get; set; }
     public string Username { get; set; }
     public float Timezone { get; set; }
}

public class Player {
     public int Id { get; set; }
     public virtual Account Account { get; set; }
     public string Team_Name { get; set; }
}

Now suppose I have a List<> of Player called Players, each team has 2 players, that means every Team_Name will be repeated twice. E.g. Team X has Player A and Player B, two entries in the List<> of Player to represent that.

What I want to achieve is pair teams against each other based on timezone, since each team has 2 players I should calculate the average timezone for each team by accessing Account.Timezone field in Player class, then find another team with closest average timezone to match the team against them.

Example

Upvotes: 2

Views: 97

Answers (2)

Yacoub Massad
Yacoub Massad

Reputation: 27861

Assuming that you have a Match class like this:

public class Match
{
    public string Team1 { get; set; }
    public string Team2 { get; set; }
}

You can do something like this with LINQ:

var matches =
    Players.GroupBy(player => player.Team_Name) //Group players by team name
        .Select(
            team => //For each team
                new
                {
                    TeamName = team.Key, //Select team name
                    AverageTimezone = //And average time zone
                        team.Average(player => player.Account.Timezone)
                })
        .OrderBy(team => team.AverageTimezone) //Order teams by average time zone
        .Select((team, index) => new {Team = team, Index = index})
        .GroupBy(item => item.Index/2) //Group each two teams together (since the teams are ordered by average timezone, each two teams will have a close timezone)
        .Select(g => g.Select(item => item.Team).ToList())
        .Select(g => new Match
        {
            Team1 = g[0].TeamName,
            Team2 = g[1].TeamName
        })
        .ToList();

Upvotes: 2

Eric J.
Eric J.

Reputation: 150108

You could use GroupBy() to group your List<Player> by Team_Name and go from there.

However, my preference would be to create a new entity Team and give that entity either Player1 and Player2 properties, or a List<Player> Players property. I would then have a getter TeamTimezone that calculates the average timezone of the players on the team.

Adding a class to represent the concept of Team more clearly expresses what your program is doing, making it more understandable and reduces the chances of bugs.

Upvotes: 1

Related Questions