按出现次数最少的数字对列表排序

本文关键字:数字 列表 排序 | 更新日期: 2023-09-27 18:13:25

我一直在玩这个相当一段时间了,但不能弄清楚或找到一个关于它的现有问题。我正在编写一个c#工具的比赛得分,我需要使一个整体的结果。对于这个结果,一些特殊的规则适用,我不知道最好的方法:

我有一个比赛结果列表(获胜者获得0分,第二名获得2分,第三名获得3分等)。为了使结果成立,我们首先对所有点求和。当这样做的时候,仍然有可能车手分享相同数量的积分。在这种情况下,我们必须看看他们的最佳结果,例如:

车手1得分:0 + 0 + 4 = 4车手2得分:2 + 2 + 0 = 4

在这种情况下,车手1将是第一名,因为他赢了最多的比赛,车手2将紧随其后,因为他只赢了一次。这应该适用于所有参与者。

更新:我的数据模型如下所示:

    public class SerieResultForPilot {
            public long Position { get; set; }
            public Pilot Pilot { get; set; }
            public List<SerieResultEntry> SerieResultEntries { get; set; }
            public long Total { get; set; }
        }
        public class SerieResultEntry {
            public long Points { get; set; }
            public long Penalties { get; set; }
        }

我当前的排序,但不能正常工作:

       var orderedList = serieResultList.OrderBy(rfp => rfp.Total);
            for (int i = 0; i < pilots.Count; i++) {
                orderedList = orderedList.ThenBy(c => c.SerieResultEntries.Count(sre => sre.Points == i));
            }

我希望任何人都能帮我解决这个问题,因为我还没有在这里找到这样的问题。

提前感谢,马克。

<

解决方案/strong>比较函数

    public class SerieResultForPilot {
            public long Position { get; set; }
            public Pilot Pilot { get; set; }
            public List<SerieResultEntry> SerieResultEntries { get; set; }
            public long Total { get; set; }
            public long CompareTo(SerieResultForPilot other) {
                var result = this.Total - other.Total;
                if (result != 0) {
                    return result;
                }
                var thisResults = this.SerieResultEntries.OrderBy(x => x.Points).Select(x => x.Points).ToArray();
                var otherResults = other.SerieResultEntries.OrderBy(x => x.Points).Select(x => x.Points).ToArray();
                for (var i = 0; i < thisResults.Length; i++) {
                    if (thisResults[i] != otherResults[i]) {
                        return thisResults[i] - otherResults[i];
                    }
                }
                return 0;
            }
        }
        public class SerieResultEntry {
            public long Points { get; set; }
            public long Penalties { get; set; }
        }
订购

    var orderedList = serieResultList.OrderBy(rfp => rfp.Total);
    foreach (var result in serieResultList) {
          orderedList = orderedList.ThenBy(c => c.CompareTo(result));
    }

按出现次数最少的数字对列表排序

您可以在类构建中实现IComparable接口。

根据您的数据模型比较方法,

可能看起来像这样

public int CompareTo(SerieResultForPilot other){
    var result this.Total - other.Total;
    if (result != 0){
        return result;
    }else{
        var thisResults = this.SerieResultEntries.OrderBy(x => x.SerieResultEntries.Points).toArray();
        var otherResults = his.SerieResultEntries.OrderBy(x => x.SerieResultEntries.Points).toArray();
        for (var i=0; i< thisResults.Count; i++){
            if (thisResults[i] != otherResults[i]){
                return thisResults[i] - otherResults[i];
            }
        }
        return 0;
    }
}

IComparable接口的文档可在这里获得https://msdn.microsoft.com/pl-pl/library/system.icomparable(v=vs.110).aspx

也许不是最有效的,但我认为这样做可以:

drivers.OrderBy(x => new { x.Sum(y => y.Points), 
    x.Sum(y => y.Points.Where(t => t.Points = 4)), x.Sum(y => y.Points.Where(t => t.Points = 3)) });

假设points是存储在每个车手的可枚举对象

查看您的代码,我认为您需要做的就是将ThenBy替换为ThenByDescending。(您希望大多数分数较低的驱动程序位于列表的顶部。)它还依赖于最大比赛分数小于车手数量-也许你需要一个<=而不是<在你的for循环?

这不是最有效的方式,但它非常聪明——我很难想出使用更少代码行的方法。

您需要首先找到no。每个车手的胜利和分数的总和,然后根据他们的分数和胜利对记录进行排序,如下面的示例所示:

public class LinqUtil<T> where T : BaseClass
{
    public static void MyScore()
    {
        List<DriverScore> scores = new List<DriverScore>
        {
            new DriverScore {driverId="driver2",score=2 },
            new DriverScore {driverId="driver2",score=2 },
            new DriverScore {driverId="driver2",score=0 },
            new DriverScore {driverId="driver1",score=0 },
            new DriverScore {driverId="driver1",score=0 },
            new DriverScore {driverId="driver1",score=4 },
        };
        var _score = (from s in scores
                    group s by s.driverId into g
                    select new
                    {
                        driverId = g.Key,
                        Win = g.Count(x => x.score == 0),
                        Score = g.Sum(x => x.score)
                    }).OrderByDescending(x=>x.Score).ThenByDescending(x=>x.Win);
        foreach(var _s in _score)
        {
            Console.WriteLine(_s.driverId + " " + _s.Win + " " + _s.Score);
        }

    }
}