I'm very new to Linq so bare with me. Can I return more than one item in a select? For instance I have a List of Fixtures (think football (or soccer for the yanks) fixtures). Each fixture contains a home and away team and a home and away score. I want to get all the teams that drew. I want to use something like
IEnumerable<Team> drew = from fixture in fixtures
where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
select fixture.HomeTeam && fixture.AwayTeam;
I know this syntax is incorrect, what I don't know is if it's possible to do this. Would I need two queries and then concatenate them?
Edit: this is really a learning thing so it's not critical to achieve this in any particular way. Basically, at this stage all i want is a list of teams that have drawn. An example usage might be that for a given list of fixtures i can find all of the drawn teams so that i could update their standings in a table by 1 point (3 for a win, 0 for a loss).
Cheers James
-
101 LINQ Samples, namely Select - Anonymous Types 1
... select new { HomeTeam = fixture.HomeTeam, AwayTeam = fixture.AwayTeam };
Mike Powell : Not the answer he's looking for. He wants a list of Teams, not a list of anonymous types with hometeam and awayteam properties.James Hay : This is true... i could get round it using anonymous types... just wondered if there was a way to get just a list of teams. If it's the only way it's the only way thoughbendewey : I agree that this doesn't return a list of teams, but i thinks its better for him to adapt his code to suport handling this anon type. If James Hay could update his question to describe his usuage that might help.Mike Powell : I think his question already describes his requirement perfectly: "I want to get a list of teams that drew." There are lots of reasons he might not want to use anonymous types here (needing to pass the list outside this method would be a common one). -
Edit: Sorry, misunderstood your original question, so rewrote answer.
You could use the "SelectMany" operator to do what you want:
IEnumerable<Team> drew = (from fixture in fixtures where fixture.Played && (fixture.HomeScore == fixture.AwayScore) select new List<Team>() { HomeTeam = fixture.HomeTeam, AwayTeam = fixture.AwayTeam }).SelectMany(team => team);
This will return a flattened list of teams that drew.
-
Or you can define a type to hold all that data:
IEnumerable<TeamCluster> drew = from fixture in fixtures where fixture.Played && (fixture.HomeScore == fixture.AwayScore) select new TeamCluster { Team1 = fixture.HomeTeam, Team2 = fixture.AwayTeam, Score1 = fixture.HomeScore, Score2 = fixture.AwayScore }; class TeamCluster { public Team Team1 { get; set; } public Team Team2 { get; set; } public int Score1 { get; set; } public int Score2 { get; set; } }
-
I think you're looking for the Union method as follows:
IEnumerable<Team> drew = (from fixture in fixtures where fixture.Played && (fixture.HomeScore == fixture.AwayScore) select fixture.HomeTeam) .Union(from fixture in fixtures where fixture.Played && (fixture.HomeScore == fixture.AwayScore) select fixture.AwayTeam);
-
An (independant) variation on John Price's solution...
IEnumerable<Team> drew = from fixture in fixtures where fixture.Played && (fixture.HomeScore == fixture.AwayScore) from team in new[]{fixture.AwayTeam, fixture.HomeTeam} select team;
You could consider adding "ParticipatingTeams" to the Fixture class to get:
IEnumerable<Team> drew = from fixture in fixtures where fixture.Played && (fixture.HomeScore == fixture.AwayScore) from team in fixture.ParticipatingTeams select team;
mattdekrey : +1 for your first query - doesn't require a contract change and is more efficient than the leading answer. -
Taking a stab at this myself I came up with the same version as 'it depends'.
Using query comprehension syntax:
IEnumerable<Team> drew = from fixture in fixtures where fixture.Played && (fixture.HomeScore == fixture.AwayScore) from team in new[]{fixture.AwayTeam, fixture.HomeTeam} select team;
Using lambda with extension methods:
IEnumerable<Team> drew = fixtures.Where(f => f.Played && f.HomeScore == f.AwayScore) .SelectMany(f => new[]{f.HomeTeam, f.AwayTeam});
Edit: I don't know if a team could have possibly played and drawn more than once in your database, but if that's possible, then you might want to make use of the
Distinct
query operator:IEnumerable<Team> drew = (from fixture in fixtures where fixture.Played && (fixture.HomeScore == fixture.AwayScore) from team in new[]{fixture.AwayTeam, fixture.HomeTeam} select team).Distinct();
or:
IEnumerable<Team> drew = fixtures.Where(f => f.Played && f.HomeScore == f.AwayScore) .SelectMany(f => new[]{f.HomeTeam, f.AwayTeam}) .Distinct();
0 comments:
Post a Comment