如何解决如何使用LinQ将特定数量的行分组?
我正在创建一个分数跟踪Web应用程序供我的朋友和我使用。跟踪器必须根据玩家玩过最少回合数的回合数对得分进行分组。
示例:如果我参加了6轮比赛,而我的一个朋友只参加了4轮比赛,那么他的所有回合都将计入比赛,并且只考虑我的4个最佳成绩。
这是我到目前为止所拥有的:
[ActionName("List")]
public async Task<IActionResult> List()
{
var allData = await _cosmosDbService.GetScoresAsync(
"SELECT * FROM c");
var countRecordData = allData.GroupBy(l => l.Player).Select(cl => new Score
{
Player = cl.Count().ToString()
}).ToList();
var minRecord = countRecordData.Min(record => record.Player);
int minRecordInt = Int32.Parse(minRecord);
var sumData = allData.GroupBy(l => l.Player).Select(cl => new Score
{
Player = cl.First().Player,Points = cl.Sum(c => c.Points),Strokes = cl.Sum(c => c.Points),}).ToList();
return View(sumData);
}
minRecord仅用于获取记录数量最少(最小数量)的播放器。我没有在其他任何地方使用它。
这是分数模型:
public class Score
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "Player")]
public string Player { get; set; }
[JsonProperty(PropertyName = "Course")]
public string Course { get; set; }
[JsonProperty(PropertyName = "Points")]
public int Points { get; set; }
[JsonProperty(PropertyName = "Strokes")]
public int Strokes { get; set; }
}
有人知道我如何达到这个要求吗?
解决方法
不知道它有多漂亮,但是您就到这里了。您可以这样做:
[ActionName("List")]
public async Task<IActionResult> List()
{
var allData = await _cosmosDbService.GetScoresAsync(
"SELECT * FROM c");
var playerRounds = allData.GroupBy(l => l.Player);
var minRounds = playerRounds.Min(x => x.Count());
var sumData = playerRounds.Select(cl => new Score
{
Player = cl.First().Player,Points = cl.OrderByDescending(x => x.Points).Take(minRounds).Sum(c => c.Points),Strokes = cl.OrderByDescending(x => x.Points).Take(minRounds).Sum(c => c.Points),}).ToList();
return View(sumData);
}
https://dotnetfiddle.net/ho1psw
,您即将实现自己想要的。这是我对我相信您正在尝试做的事情的看法。
如果数据量很小,则多次使用GroupBy
都没关系,但是最好只创建一次组:
var groupings = allData
.GroupBy(
score => score.Player,(player,scores) => new
{
Player = player,Scores = scores.ToList()
})
.ToList();
呼叫ToList
将确保每个玩家的分数收集都被枚举并分配到列表中。
我不确定您确定最小记录数的部分。计算Player
属性的最小值似乎很奇怪,我认为这是播放器的名称。
在这里,我计算所有玩家的最低分数:
var minScoreCount = groupings.Min(grouping => grouping.Scores.Count);
在最后一部分中,您必须使用Take(minScoreCount)
仅为每个玩家获取前N个得分。我认为这是您自己的代码中缺少的部分。
var sumData = groupings.Select(grouping => new Score
{
Player = grouping.Player,Points = grouping.Scores
.OrderByDescending(score => score.Points)
.Take(minScoreCount)
.Sum(score => score.Points),Strokes = grouping.Scores
.OrderBy(score => score.Strokes)
.Take(minScoreCount)
.Sum(score => score.Strokes)
}).ToList();
如果您不需要对Points
和Strokes
的分数进行不同的排序,则可以在ToList
内部的GroupBy
之前对分数进行排序,以减少数字代码遍历分数列表的时间。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。