对象的C#排序,多重标准 [英] C# Ranking of objects, multiple criteria
问题描述
我建立了一个LAN第三方网站,我写这将允许使用循环赛比赛的插件。
一切都进展顺利,但我对最有效的方式有些问题在两个标准来排名。
基本上,我想下面的排名布局:
排名赢得TotalScore
PersonE 1 5 50
PersonD 2 3.5 37
人物2 3.5 37
PersonC 4 2.5 26
PersonB 5 2.5 24
PersonF 6 0 12
在SQL服务器,我会用:
SELECT
[人],
RANK()OVER(ORDER BY DESC获胜,TotalScore DESC)排名]
[WINS]
[总得分]
现在,我只有列表,字典,等与
工作具体做法是:
词典< TournamentTeam,双>胜=新词典< TournamentTeam,双>();
字典< TournamentTeam,双>分数=新词典< TournamentTeam,双>();
有没有办法做LINQ排名的这种风格?
如果不是,是否有一个的扩展的方式,让我以后采取占到赢取损失绘制,而不是仅仅赢,如果我选择?
编辑:
我TheSoftwareJedi的回答改编:
私有类RRWinRecord:IComparable的
{
公众诠释胜{搞定;组; }
公众诠释损失{搞定;组; }
公众诠释绘制{搞定;组; }
公共双overalScore值{搞定;组; }
公共双WinRecord
{
得到
{
返回this.Wins * 1.0 + this.Draws * 0.5 + this.Losses * 0.0;
}
} 公众诠释的CompareTo(obj对象){...} 公众覆盖布尔等于(obj对象){...}
公共覆盖INT GetHash code(){...}
公共静态布尔运算符==(RRWinRecord LHS,RHS RRWinRecord){...}
公共静态布尔运算符!=(RRWinRecord LHS,RHS RRWinRecord){...}
公共静态布尔运算符>(RRWinRecord LHS,RHS RRWinRecord){...}
公共静态布尔运算符≤(RRWinRecord LHS,RHS RRWinRecord){...}
公共静态布尔运算符> =(RRWinRecord LHS,RHS RRWinRecord){...}
公共静态布尔运算符< =(RRWinRecord LHS,RHS RRWinRecord){...}
}... INT R = 1,lastRank = 1;
RRWinRecord lastRecord = NULL; 从变种位居小组=以records.Keys
让teamRecord =记录[队伍]
排序依据teamRecord下降
选择新RRRank(){团队=队,排名= R ++,记录= teamRecord}; 的foreach(在队伍中排名VAR)
{
如果(rank.Record = NULL&放大器;!&安培; lastRecord == rank.Record)
{
rank.Rank = lastRank;
} lastRecord = rank.Record;
lastRank = rank.Rank; 字符串scoreDescription =的String.Format({0} - {1} - {2},rank.Record.Wins,rank.Record.Losses,rank.Record.Draws);
产量返回新TournamentRanking(rank.Team,rank.Rank,scoreDescription);
} 产生中断;
这应该非密集排名工作:
静态类节目
{ 静态的IEnumerable<结果> GetResults(词典< TournamentTeam,双>胜字典< TournamentTeam,双>分)
{
INT R = 1;
双lastWin = -1;
双lastScore = -1;
INT lastRank = 1; 的foreach(VAR排名从名字wins.Keys
让分数=得分[名]
让赢=胜[名]
排序依据赢降,降得分
选择新的结果{名称=名称,等级= R ++,得分=得分,赢赢=})
{
如果(lastWin == rank.Win&放大器;&安培; lastScore == rank.Score)
{
rank.Rank = lastRank;
}
lastWin = rank.Win;
lastScore = rank.Score;
lastRank = rank.Rank;
产生收益排名;
}
}
}类结果
{
公共TournamentTeam名称;
公众诠释排名;
公共双积分;
公共双赢;
}
I am building a plugin for a LAN party website that I wrote that would allow the use of a Round Robin tournament.
All is going well, but I have some questions about the most efficient way to rank over two criteria.
Basically, I would like the following ranking layout:
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
In SQL server, I would use:
SELECT
[Person],
RANK() OVER (ORDER BY Wins DESC, TotalScore DESC) [Rank],
[Wins],
[TotalScore]
Now, I only have List, Dictionary, and etc. to work with
Specifically:
Dictionary<TournamentTeam, double> wins = new Dictionary<TournamentTeam, double>();
Dictionary<TournamentTeam, double> score = new Dictionary<TournamentTeam, double>();
Is there a way to do this style of ranking with LINQ?
If not, is there an extensible way that would allow me later to take in to account Win-Loss-Draw instead of just wins if I choose to?
Edit:
My adaptation of TheSoftwareJedi's answer:
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;
This should work for a non-dense rank:
static class Program
{
static IEnumerable<Result> GetResults(Dictionary<TournamentTeam, double> wins, Dictionary<TournamentTeam, double> scores)
{
int r = 1;
double lastWin = -1;
double lastScore = -1;
int lastRank = 1;
foreach (var rank in from name in wins.Keys
let score = scores[name]
let win = wins[name]
orderby win descending, score descending
select new Result { Name = name, Rank = r++, Score = score, Win = win })
{
if (lastWin == rank.Win && lastScore == rank.Score)
{
rank.Rank = lastRank;
}
lastWin = rank.Win;
lastScore = rank.Score;
lastRank = rank.Rank;
yield return rank;
}
}
}
class Result
{
public TournamentTeam Name;
public int Rank;
public double Score;
public double Win;
}
这篇关于对象的C#排序,多重标准的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!