ваша проблема звучит действительно интересно. Я много играл в соревнованиях (по волейболу), и в случае равных очков (где очки зарабатываются на основе выигранных или проигранных матчей), команда с наибольшим количеством очков и наименьшим количеством контрапунктов будет отсортирована первой. Так что в этом случае, вместо того, чтобы реально смотреть на отдельные матчи, просто рассортируйте по общему количеству выигранных и проигранных голов.
Так что тогда будет легко:
LeagueTable.all.order('points desc, goals_won desc, goals_lost desc')
что, я думаю, было бы довольно приличным порядком. Затем выбирается самая атакующая команда. Вы также предпочитаете самую оборонительную команду, сортируя по order('points desc, goals_lost desc, goals_won desc')
.
Но это всего лишь ярлык. Я полагаю, что вы не вправе изменять правила сортировки, как хотите, и это действительно хорошая проблема, чтобы взломать. Вот некоторый код, как я бы подошел к нему
all_teams_simple_sort = LeagueTable.all.sort('points desc')
all_teams_sorted = []
teams_equal_points = []
prev_team = all_teams_simple_sort[1]
prev_points = all_teams_simple_sort[1].points
(2..all_teams_simple_sort.size).each do |team_index|
team = all_teams_simple_sort[team_index]
if team.points == prev_team.points
teams_equal_points << prev_team if teams_equal_points.size == 0
teams_equal_points << team
else
if teams_equal_points.size > 0
add_equals_sorted_to all_teams_sorted, teams_equal_sorted
teams_equal_sorted = []
else
all_teams_sorted << prev_team
end
all_teams_sorted << team
end
prev_team = team
end
Это должно охватить все команды, объединить все команды с равными очками и добавить все остальные, если необходимо.
Теперь нам нужно только написать самую сложную функцию add_equals_sorted_to
, которая добавит команды с равными точками в правильном порядке к сортировке результатов.
def add_equals_sorted_to(result_sorted, equals_unsorted)
team_ids = equals_unsorted.collect(&:team_id)
# get all the matches for between those teams
matches = Match.where('team_home_id in (?) and team_away_id in (?)', team_ids.join(','), team_ids.join(','))
# create an empty hash for each team
team_score = {}
team_ids.each {|id| team_scores[id] = {:won => 0, :lost => 0} }
matches.each do |match|
team_scores[match.team_home_id] = {:won => team_scores[match.team_home_id][:won] + match.score_home, :lost => team_scores[match.team_home_id][:lost] + match.score_away }
team_scores[match.team_away_id] = {:won => team_scores[match.team_away_id][:won] + match.score_away, :lost => team_scores[match.team_home_id][:lost] + match.score_home }
end
# get the team with the highest :won and add to result_sorted
# and repeat until no more left
end
Этот код не тестировался :) Но я надеюсь, что вы должны начать.