对象的C#排序,多重标准 [英] C# Ranking of objects, multiple criteria

查看:241
本文介绍了对象的C#排序,多重标准的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立了一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆