c# - 如何使用 LinQ 对特定数量的行进行分组?

标签 c# asp.net .net linq

我正在创建一个分数跟踪 Web 应用程序供我和我的 friend 使用。跟踪器必须根据轮数最少的玩家已经玩了多少轮来对分数进行分组。

示例:如果我玩了 6 轮,而我的一个 friend 只玩了 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; }
}

有谁知道我怎样才能达到这个要求?

最佳答案

您即将实现您想要的目标。这是我对我认为您正在尝试做的事情的看法。

如果数据量很小,多次使用 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();

如果您不需要对 PointsStrokes 的分数进行不同的排序,您可以在 ToList 之前对分数进行排序GroupBy 减少了代码遍历分数列表的次数。

关于c# - 如何使用 LinQ 对特定数量的行进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64209194/

相关文章:

c# - 带指针的 PInvoke - C++ 到 C#

c# - 在数据表中添加两个数组列表

c# - .NET Core Web 项目 - 使用命令行参数

C# HashSet VS C++ std::unordered_set 自定义类键。 C++ 更慢……不可能。如何达到C#的速度?

c# - 如何限制文本框的表情符号范围 u2600-u26FF

c# - 跨多个应用程序池的 ASP.Net C# 共享 session

c# - 为什么抽象类要实现抽象基类的抽象方法?

c# - MAPIFolder 已弃用,因此 Outlook 编程的解决方法?

c# - OxyPlot 的 LinearAxis 需要 margin

c# - 如何在 ASP.Net Core 2.x 的 Action Filter 中获取配置、Cookie 和 DBContext