Please review this small program I wrote to create a World Cup Group Table. You feed the program match info, and it builds a table based on that info.
def table_for(matches)
# Defaults that each team in the table should have
defaults = { goals_for: 0, points: 0 }
# Using the matches, let's create a hash for each team involved in a match
teams = matches.each_with_object([]) do |match, array|
array.push({ name: match[:home_team] }.merge!(defaults))
array.push({ name: match[:away_team] }.merge!(defaults))
end
# We have 6 matches; each match involves 2 teams; we have 12 teams in our array.
# Each team plays 3 matches, so we have 4 unique.
teams.uniq
# Loop through matches to build the table.
matches.each do |match|
# We only want to calculate data for matches that were played
if match[:home_score].present? && match[:away_score].present?
# Grab the teams for this particular match from the list of teams
home_team = teams.detect { |team| team[:name] == match[:home_team] }
away_team = teams.detect { |team| team[:name] == match[:away_team] }
# Compute goals_for
home_team[:goals_for] += match[:home_score]
away_team[:goals_for] += match[:away_score]
# Home team wins
if match[:home_score] > match[:away_score]
home_team[:points] += 3
# Away team wins
elsif match[:home_score] < match[:away_score]
away_team[:points] += 3
# It's a draw
else
home_team[:points] += 1
away_team[:points] += 1
end
end
end
teams
end
The rules are a win earns three points, a draw one point, a loss zero points.
For example, if we feed the method this match data:
[
{ id: 1, home_team: "Honduras", away_team: "Chile", home_score: 0, away_score: 1 },
{ id: 2, home_team: "Spain", away_team: "Switzerland", home_score: 0, away_score: 1 },
{ id: 3, home_team: "Chile", away_team: "Switzerland", home_score: 1, away_score: 0 },
{ id: 4, home_team: "Spain", away_team: "Honduras", home_score: 2, away_score: 0 },
{ id: 5, home_team: "Chile", away_team: "Spain", home_score: 1, away_score: 2 },
{ id: 6, home_team: "Honduras", away_team: "Switzerland", home_score: 0, away_score: 0 }
]
We should see this table:
| TEAM | GF | POINTS |
| Spain | 4 | 6 |
| Chile | 3 | 6 |
| Switzerland | 1 | 4 |
| Honduras | 0 | 0 |
How can I improve this? If there a better way to get the unique teams from the match info? That parts looks convoluted. I also feel that the method is too large.