2011-04-20 43 views
0

請查看下面的簡短示例代碼,告訴我是否有更好,更緊密的方式來編寫LINQ查詢。父母課程只是學生的名字和考試成績數據的列表。孩子班級是一個單一的考試成績數據。我想從所有TestScore值中找出最差(或最好)的分數,然後確定得分最高的學生。使用LINQ從所有子記錄中查找字段的最大值或最小值

謝謝!

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 
+0

看到這麼長的VB.NET代碼讓我噁心:/ – 2011-04-20 20:10:30

+1

你真的不需要那裏所有的樣板代碼。查詢本身可以很容易地推斷出我們需要了解的類。 – 2011-04-20 20:12:38

+0

OT:除了我以外,其他人都認爲「LINQ Query」這個短語是多餘的嗎?但我想不出有更好的方式說出來! – 2011-04-21 21:38:17

回答

2

我不是一個VB的人所以有可能一些語法錯誤,但我可以建議兩方面的改進:

  • 而不是使用選擇再敏,使用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了,所以我們並不真正需要它與查詢結果。請注意,儘管如此,仍然可能有多名學生最差。

+0

我更喜歡你的答案,因爲它從查詢中刪除冗餘數據(worstScore)。感謝您指出Min投影。 – blueshift 2011-04-21 12:56:32

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。)

+0

感謝您花時間回覆。 MaxBy和MinBy對我來說可能對我有用。現在,我會追求一種使用本地LINQ語法的方法。 – blueshift 2011-04-21 12:59:09

0

如何

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

使用OrderByDescendingMax找到最好的成績。

+0

感謝您的回覆。它非常簡約,這正是我最初尋求的。 – blueshift 2011-04-21 13:00:26