我已经玩了很长一段时间,但是无法弄清楚或找到关于它的现有问题。我正在为比赛得分编写一个C#工具,我需要做出总体结果。对于这个结果,一些特殊规则适用于我无法找到最佳方法:
我有一个包含比赛结果的列表(获胜者获得0分,第二名获得2分,第三名获得3等等)。为了使结果有效,我们首先按所有点的总和进行排序。当这样做时,仍有可能驱动程序共享相同数量的点数。在这种情况下,我们必须查看他们的最佳结果,例如:
车手1得分:0 + 0 + 4 = 4 司机2得分:2 + 2 + 0 = 4
在这种情况下,驾驶员1将首先是因为他获得了最多的胜利,因此他只有一次胜利。这适用于所有参与者。
更新 我看到的数据模型如下:
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));
}
我希望有人可以帮我解决这个问题,因为我在这里找不到这样的问题。
提前致谢, 标记
解决方案 比较功能
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));
}
答案 0 :(得分:2)
你可以在类构建中围绕结果实现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
答案 1 :(得分:0)
也许不是效率最高的,但我认为这样做会很好:
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)) });
假设点是为每个驱动程序存储的可枚举。
答案 2 :(得分:0)
查看您的代码,我认为您需要做的就是将ThenBy
替换为ThenByDescending
。 (你希望列表顶部大多数得分较低的驾驶员。)它还依赖于最大比赛得分低于驾驶员数量 - 也许你需要一个<=
而不是<
而不是for
循环中的{{1}}?
这不是最最有效的方式,但它非常聪明 - 我很难想出一些使用更少行代码的东西
答案 3 :(得分:0)
你需要先找不到。获胜者和每位车手的得分总和,然后根据他们的得分和胜利对记录进行排序,如下例所示:
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);
}
}
}