同一天內,相同課程(如「語文課」)應**連續排在相鄰節次**,避免間隔。
result = result.Select(day => day
.OrderBy(course => course == "自修課" ? 1 : 0) // 自修課後置
.ThenBy(_ => Guid.NewGuid()) // 其他隨機
.GroupBy(course => course) // 同課分組
.SelectMany(g => g) // 組內保持順序,組間連續
.ToArray()
).ToArray();
OrderBy(...) 先按「是否自修課」分桶,自修課排後;同桶內用 Guid.NewGuid() 打亂。GroupBy(course => course) 將相同課程聚合成一組,**保持原序**(LINQ GroupBy 穩定)。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();
OrderBy 階段加入權重,而非依賴 GroupBy。EqualityComparer.Default ,大小寫敏感;若課程名可能大小寫不一,先 .Select(c => c.Trim()) 統一。GroupBy + SelectMany 是「同值連續排序」的標準 LINQ 慣用語**,簡潔、聲明式、無副作用,適用於課程表、任務調度、報表分組等場景。