c# - 使用 LINQ 查询或类似方法优化运动员比赛列表
问题描述
我正在尝试构建一个函数来优化运动员在比赛中的比赛结果。假设我有一类运动员:
public class Athlete
{
public int ID {get; set; }
public string Name { get; set; }
public int RunningAbility { get; set; }
public int SwimmingAbility { get; set; }
public readonly List<Attempt> { get; set; }
}
每位运动员在比赛中进行 2 次尝试。他们可以参加两次游泳比赛,两次跑步比赛,也可以各做一次。唯一的规定是跑步者和游泳者的人数必须相等;因此,如果有 3 名运动员,则需要进行 6 次尝试——3 次跑步和 3 次游泳。
Attempt 类如下所示:
public class Attempt
{
public string AthleteID { get; set; }
public string EventName { get; set; }
}
我一直在试图弄清楚如何制作一个具有最佳方案的尝试列表。
public void Main(){
var people = new List<Athlete>() {
new Athlete()
{
Name = "Bob",
RunningAbility = 10,
SwimmingAbility = 10
},
new Athlete()
{
Name = "Joe",
RunningAbility = 8,
SwimmingAbility = 2
},
new Athlete()
{
Name = "Sue",
RunningAbility = 3,
SwimmingAbility = 7
},
};
var attempts = GetBestPossible(people);
}
private List<Attempt> GetBestPossible(List<People> people)
{
var attempts = new List<Attempt>();
//Each Person must compete twice and can either use both attempts in same event or one in each event
//The entire team Must have equal attempts for running and swimming - i.e. 3 attempt swimming and 3 attempts running in this case.
//How would I make a linq query or comparable solution on people that would give me a
//list of attempts with the max ability utilized for both events?
//Expected outcome for attempts list would be
//Name Event
//Bob Running
//Bob Swimming
//Joe Running
//Joe Running
//Sue Swimming
//Sue Swimming
//Meets criteria of having each Person attempt twice
//and equal attempts in both events with MAX ability
return attempts;
}
有谁知道是否有办法用 Linq 做到这一点,或者如果给定的细节不可能做到这一点?我不知道从哪里开始,所以非常感谢任何帮助!
编辑:List<Attempt>
向我的班级添加了一个属性Person
,我仍然不确定如何解决我的问题,但我想我需要编写一个函数,循环遍历每个运动员实例的所有可能结果,然后计算并以某种方式确定哪个结果是最适合这两个事件。
解决方案
这里有一些希望能以某种方式帮助解决问题的方法。
您有两个游戏/比赛,让我们为它们创建一个enum
:
//...
public enum Competitions { Running, Swimming }
//...
类Attempt
,最大。Athlete
无论比赛类型如何,每个对象都有两个实例。
//...
public class Attempt
{
public Competitions Competition { get; set; }
public int Score { get; set; }
}
//...
Athlete
班级:
//...
public class Athlete
{
public string Name { get; set; }
public readonly List<Attempt> Attempts = new List<Attempt>();
public override string ToString() => Name;
}
//...
还有一个类,将是每个运动员的报告/统计/状态(您可以命名)条目。
//...
public class Statistics
{
public string Name { get; set; }
public int Running { get; set; }
public int Swimming { get; set; }
public int TotalScore { get => Running + Swimming; }
public int RunningRank { get; set; }
public int SwimmingRank { get; set; }
public int GeneralRank { get; set; }
}
//...
在您的实现中,您List<Athlete>
填写了一些条目,例如:
//...
List<Athlete> Athletes = new List<Athlete>();
private void CreateList()
{
Athletes.Clear();
var jim = new Athlete { Name = "Jim" };
jim.Attempts.Add(new Attempt { Competition = Competitions.Swimming, Score = 1 });
jim.Attempts.Add(new Attempt { Competition = Competitions.Swimming, Score = 2 });
var joe = new Athlete { Name = "Joe" };
joe.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 7 });
joe.Attempts.Add(new Attempt { Competition = Competitions.Swimming, Score = 2 });
var sue = new Athlete { Name = "Sue" };
sue.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 3 });
sue.Attempts.Add(new Attempt { Competition = Competitions.Swimming, Score = 7 });
var bob = new Athlete { Name = "Bob" };
bob.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 10 });
bob.Attempts.Add(new Attempt { Competition = Competitions.Swimming, Score = 10 });
var ben = new Athlete { Name = "Ben" };
ben.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 5 });
var sam = new Athlete { Name = "Sam" };
sam.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 6 });
sam.Attempts.Add(new Attempt { Competition = Competitions.Running, Score = 4 });
Athletes.AddRange(new[] { jim, joe, sue, bob, ben, sam });
}
//...
现在让我们为每个成员创建一个统计数据或报告,其中他们的跑步和游泳尝试的总和相等。
//...
private IEnumerable<Statistics> CreateStatistics()
{
var ath = Athletes.Where(x => x.Attempts.Count() == 2
&& x.Attempts.First().Competition != x.Attempts.Last().Competition);
var abi = (from a in ath
select new Statistics
{
Name = a.Name,
Running = a.Attempts
.First(r => r.Competition == Competitions.Running).Score,
Swimming = a.Attempts
.First(s => s.Competition == Competitions.Swimming).Score,
}).ToList();
foreach (var a in abi)
{
a.RunningRank = 1 + abi.Select(r => r.Running).OrderByDescending(r => r)
.ToList().IndexOf(a.Running);
a.SwimmingRank = 1 + abi.Select(s => s.Swimming).OrderByDescending(s => s)
.ToList().IndexOf(a.Swimming);
a.GeneralRank = 1 + abi.Select(t => t.TotalScore).OrderByDescending(t => t)
.ToList().IndexOf(a.TotalScore);
}
return abi;
}
//...
结果是:
如您所见,查询仅从列表中选择了三个成员,并为每个成员创建了一个统计条目,显示他们的得分并计算他们在每场比赛中的排名,以及总排名或总排名。
祝你好运。
推荐阅读
- python - 如何使用 Python3 使用 Apache Libcloud 在 S3 和 GCS 上下载和上传文件?
- java - TaskUtils$LoggingErrorHandler - 计划任务中发生意外错误。java.lang.IllegalStateException:会话/EntityManager 已关闭
- sql - SQL - 使用 LEFT JOIN 子句返回空值的 SUM TotalValue
- mqtt - 如何使用 Mosquitto 创建 REST API,例如 arest.io
- python - 如何远程运行django?
- ruby - 匹配多行模式的正则表达式
- wordpress - ToggleControl 未应用于保存部分
- javascript - 强制不同的 npm 模块共享相同的依赖项
- ffmpeg - ffmpeg 保留原始文件日期?
- python - 列表中的 ElasticSearch 查询以包含 X 并包含 X 以外的其他内容