使用LINQ从所有子记录中查找字段的MAX或MIN

时间:2011-04-20 20:03:20

标签: .net vb.net linq

请查看我下面的简短示例代码,并告诉我是否有更好,更严格的方式来编写LINQ查询。父类只是学生的名字和测试分数数据列表。子类是单个测试分数数据。我想找出所有TestScore值中最差(或最好)的分数,然后确定得分最高的学生。

谢谢!

Dim query = From s In studentList _
            Where s.ScoreList.Select(Function(d) d.TestScore).Min _
                = studentList.SelectMany(Function(g) g.ScoreList).Select(Function(h) h.TestScore).Min _
            Select StudentName = s.Student, _
                   WorstScore = s.ScoreList.Select(Function(g) g.TestScore).Min

3 个答案:

答案 0 :(得分:2)

我不是VB人员,因此可能存在一些语法错误,但我可以建议两个改进:

  • 不使用Select then Min,而是使用接受投影的Min的重载
  • 每次迭代都找不到总体最小值;只做一次:

    Dim worstScore = studentList.SelectMany(Function(g) g.ScoreList) _
                                .Min(Function(h) h.TestScore)
    
    Dim query = From s In studentList _
                Where s.ScoreList.Min(Function(d) d.TestScore) = worstScore
                Select s.Student
    

请注意,我已从查询中删除了匿名类型 - 我们已经知道worstScore,因此我们并不需要查询结果。请注意,可能仍有多名学生 但成绩最差。

答案 1 :(得分:0)

如果我是你,我会做的第一件事是将MinimumScoreMaximumScore属性添加到StudentScores使AddScore跟踪你的​​最低和最高分数到目前为止已见过。现在,对于给定的学生,您可以在O(1)时间内找到这些内容,而不是O(n)时间

然后你要做的是编写MaxByMinBy的实现。我不会说流利的VB,但你可以在之前的answer中找到C#中MaxBy的实现,并相应地转换为VB。

最后,完成所有这些后,你可以说

studentWithBestScore = studentList.MaxBy(s => s.MaximumScore);
var bestScore = studentWithBestScore.MaximumScore;

(同样,你必须将它转换为VB。)

答案 2 :(得分:0)

怎么样

Dim query = studentList.OrderBy(Function(d) d.ScoreList.Select(Function(d) d.TestScore).Min).First()

使用OrderByDescendingMax找到最佳分数。