首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

LINQ 實現課程表「同課連續排課」:GroupBy + SelectMany 技巧

     編輯:程式設計綜合問答

需求

同一天內,相同課程(如「語文課」)應**連續排在相鄰節次**,避免間隔。

核心一行代碼

result = result.Select(day => day
    .OrderBy(course => course == "自修課" ? 1 : 0)   // 自修課後置
    .ThenBy(_ => Guid.NewGuid())                    // 其他隨機
    .GroupBy(course => course)                      // 同課分組
    .SelectMany(g => g)                             // 組內保持順序,組間連續
    .ToArray()
).ToArray();

原理解析

  1. OrderBy(...) 先按「是否自修課」分桶,自修課排後;同桶內用 Guid.NewGuid() 打亂。
  2. GroupBy(course => course) 將相同課程聚合成一組,**保持原序**(LINQ GroupBy 穩定)。
  3. SelectMany(g => g) 依次展開每組,**同課天然連續**;組與組之間按 GroupBy 迭代順序(即首次出現順序)排列。

完整上下文示例

var result = Enumerable.Range(0, 5)
    .Select(_ => Enumerable.Range(0, 6).Select(__ => "").ToArray())
    .ToArray();

// ... 隨機填充課程(略) ...

// 連續排課後處理
result = result.Select(day => day
    .OrderBy(c => c == "自修課" ? 1 : 0)
    .ThenBy(_ => Guid.NewGuid())
    .GroupBy(c => c)
    .SelectMany(g => g)
    .ToArray()
).ToArray();

注意點

  • 若某課程節次 > 1 且需**強制連續**,上述代碼完美滿足。
  • 若還需**「語文課必在上午前 3 節」**等位置約束,需在 OrderBy 階段加入權重,而非依賴 GroupBy。
  • GroupBy 預設使用 EqualityComparer.Default,大小寫敏感;若課程名可能大小寫不一,先 .Select(c => c.Trim()) 統一。

總結

GroupBy + SelectMany 是「同值連續排序」的標準 LINQ 慣用語**,簡潔、聲明式、無副作用,適用於課程表、任務調度、報表分組等場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved