ラウンド ロビン トーナメントの使用を可能にする、私が書いた LAN パーティー Web サイト用のプラグインを構築しています。
すべて順調に進んでいますが、2 つの基準でランク付けする最も効率的な方法についていくつか質問があります。
基本的には、次のランキング レイアウトを希望します。
Rank Wins TotalScore
PersonE 1 5 50
PersonD 2 3.5 37
PersonA 2 3.5 37
PersonC 4 2.5 26
PersonB 5 2.5 24
PersonF 6 0 12
SQL サーバーでは、次を使用します。
SELECT
[Person],
RANK() OVER (ORDER BY Wins DESC, TotalScore DESC) [Rank],
[Wins],
[TotalScore]
今、私は作業するリスト、辞書などしか持っていません
具体的には:
Dictionary<TournamentTeam, double> wins = new Dictionary<TournamentTeam, double>();
Dictionary<TournamentTeam, double> score = new Dictionary<TournamentTeam, double>();
このスタイルのランキングを LINQ で行う方法はありますか?
そうでない場合、選択した場合に勝つだけでなく、後で勝敗引き分けを考慮することができる拡張可能な方法はありますか?
編集:
TheSoftwareJediの回答の私の適応:
private class RRWinRecord : IComparable
{
public int Wins { get; set; }
public int Losses { get; set; }
public int Draws { get; set; }
public double OverallScore { get; set; }
public double WinRecord
{
get
{
return this.Wins * 1.0 + this.Draws * 0.5 + this.Losses * 0.0;
}
}
public int CompareTo(object obj) { ... }
public override bool Equals(object obj) { ... }
public override int GetHashCode() { ... }
public static bool operator ==(RRWinRecord lhs, RRWinRecord rhs) { ... }
public static bool operator !=(RRWinRecord lhs, RRWinRecord rhs) { ... }
public static bool operator >(RRWinRecord lhs, RRWinRecord rhs) { ... }
public static bool operator <(RRWinRecord lhs, RRWinRecord rhs) { ... }
public static bool operator >=(RRWinRecord lhs, RRWinRecord rhs) { ... }
public static bool operator <=(RRWinRecord lhs, RRWinRecord rhs) { ... }
}
...
int r = 1, lastRank = 1;
RRWinRecord lastRecord = null;
var ranks = from team in records.Keys
let teamRecord = records[team]
orderby teamRecord descending
select new RRRank() { Team = team, Rank = r++, Record = teamRecord };
foreach (var rank in ranks)
{
if (rank.Record != null && lastRecord == rank.Record)
{
rank.Rank = lastRank;
}
lastRecord = rank.Record;
lastRank = rank.Rank;
string scoreDescription = String.Format("{0}-{1}-{2}", rank.Record.Wins, rank.Record.Losses, rank.Record.Draws);
yield return new TournamentRanking(rank.Team, rank.Rank, scoreDescription);
}
yield break;