C# 使用 GroupBy 將資料分組 示範

依據指定的鍵(Key) 將清單中的內容進行分組,回傳結果為該組的 Key 和所有內容清單所組合而成的清單。

建立測試物件:
    
/// <summary>
/// 測驗成績
/// </summary>
/// <param name="No">學號</param>
/// <param name="Score">成績</param>
public record TestScore(string No, int Score);
    

建立測試資料:
    
// 測驗成績清單
TestScore[] testScores =
{
    new("001", 70),
    new("002", 80),
    new("003", 90),
    new("004", 80),
    new("005", 70),
    new("006", 60),
};
    

依照成績分組:
    
List<IGrouping<int,TestScore>> list = testScores
    .GroupBy(x => x.Score)
    .ToList();
    

輸出結果:
    
list.ForEach(group =>
{
    Console.WriteLine($"Score:{group.Key}, Count:{group.Count()}");
    group.ToList().ForEach(item => Console.WriteLine($"\tNo:{item.No}, Score:{item.Score}"));
});

/*
Score:70, Count:2
        No:001, Score:70
        No:005, Score:70
Score:80, Count:2
        No:002, Score:80
        No:004, Score:80
Score:90, Count:1
        No:003, Score:90
Score:60, Count:1
        No:006, Score:60
*/
    

因為測試資料中的所有人分數尾數都是 0 ,讓我們來調整一下測試資料,使其更符合現實情況
    
// 測驗成績清單
TestScore[] testScores =
{
    new("001", 71),
    new("002", 82),
    new("003", 93),
    new("004", 84),
    new("005", 75),
    new("006", 66),
};
    

因為沒有成績有重複,所以就變成一人一組了,有分組和沒分組一樣
    
list.ForEach(group =>
{
    Console.WriteLine($"Score:{group.Key}, Count:{group.Count()}");
    group.ToList().ForEach(item => Console.WriteLine($"\tNo:{item.No}, Score:{item.Score}"));
});

/*
Score:71, Count:1
        No:001, Score:71
Score:82, Count:1
        No:002, Score:82
Score:93, Count:1
        No:003, Score:93
Score:84, Count:1
        No:004, Score:84
Score:75, Count:1
        No:005, Score:75
Score:66, Count:1
        No:006, Score:66
*/
    

如果我們想要讓分組的方式為每 10 分一組,例如 70 ~ 79 分一組,最簡單的方式就是在分組時將分數除以 10 即可
    
List<IGrouping<int,TestScore>> list = testScores
    .GroupBy(x => x.Score / 10)
    .ToList();
    

這樣輸出的結果就可以依照我們想要的分組方式了!
    
list.ForEach(group =>
{
    Console.WriteLine($"Score:{group.Key}, Count:{group.Count()}");
    group.ToList().ForEach(item => Console.WriteLine($"\tNo:{item.No}, Score:{item.Score}"));
});

/*
Score:7, Count:2
        No:001, Score:71
        No:005, Score:75
Score:8, Count:2
        No:002, Score:82
        No:004, Score:84
Score:9, Count:1
        No:003, Score:93
Score:6, Count:1
        No:006, Score:66
*/
    

再接下來可能會遇到的就是排序的問題了,可以參考:C# LINQ 排序介紹 (OrderBy, ThenBy)

延伸閱讀: C# LINQ 從 0 到 1 基礎教學

參考資料:
Microsoft.Learn - Enumerable.GroupBy Method

留言