0

I would like to select objects(A) where one of property is list of objects(B) and based on criteria of object A and object B select only matching.

For example:

class Team //objects A
{
    public string TeamName { get; set; }
    public int StadiumName { get; set; }
    public List<Player> Players { get; set; }
    public string Country { get; set; }
}

class Player //objects B
{
    public string Name { get; set; }
    public int Age { get; set; }
    public float Height { get; set; }
    public float Weight { get; set; }
}

I have teams with some players and I would like to select teams where the country is England and inside that team only Players that are older than 28. For example there are three teams and every team have 16 players. Only two of those teams are from England. So the result should be list of two teams that have list of player only older than 28 (so list of players may consist of 0 to 16 players)

I wrote some linq but it either returns team with all players (16 of them) or returns null if there is no player older than 28:

teams.Where(team => team.Country == "England" && team.Players.Any(player => (player.Age > 28)));

2 Answers 2

6

Your requirements essentially necessitate creating a new Team object with a reduced set of players (or alternatively permanently removing the younger players from the original Team object).

var teamsEnglandOnlyOver28Years =
    teams
    // Only teams from England
    .Where(t => t.Country == "England")
    // Create a new instance with only the older players
    .Select(t => new Team()
    {
        TeamName = t.TeamName,
        StadiumName = t.StadiumName,
        Players = t.Players.Where(p => p.Age > 28).ToList(),
        Country = t.Country       
    });

This may or may not be what you actually intend. It seems a bit awkward because, for example, the team name is the same as for the original team but the roster is reduced.

Sign up to request clarification or add additional context in comments.

2 Comments

And if Team has a lot of properies should i map all of them inside Select(t => new Team(){....} or is there a shortcut? Because only Player list will differ
In the event Team has a lot of properties, I'd either use a framework like AutoMapper or add a constructor to Team that accepts a Team and does the mapping there. I like the proposed answer a lot with the one caveat that if you expect to do this in more than one place, Alex Sikilinda's answer below may be more suitable to your needs. Both are good, in the right situation
3

Another option is to have a GetPlayers(Func<Player,bool> condition) method which you can use to get filtered players:

class Team
{
    public string TeamName { get; set; }
    public int StadiumName { get; set; }
    public List<Player> Players { get; set; }
    public string Country { get; set; }

    public IEnumerable<Player> GetPlayers(Func<Player, bool> condition)
    {
        return Players.Where(condition);
    }
}

This is a better solution than returning a new object with filtered players because filtered players are not getting lost, and you can access them from Players property.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.