[英]Sorting list by range using LINQ in C#
我有一個這樣的列表:
List<Student> students = new List<Student>
{
new Student { Name = "M", Scores = new int[] { 94, 92, 91, 91 } },
new Student { Name = "I", Scores = new int[] { 66, 87, 65, 93, 86} },
new Student { Name = "C", Scores = new int[] { 76, 61, 73, 66, 54} },
new Student { Name = "D", Scores = new int[] { 94, 55, 82, 62, 52} },
new Student { Name = "P", Scores = new int[] { 91, 79, 58, 63, 55} },
new Student { Name = "E", Scores = new int[] { 74, 85, 73, 75, 86} },
new Student { Name = "P", Scores = new int[] { 73, 64, 53, 72, 68} },
}
有什么方法可以計算每個學生的平均分並按范圍顯示。 結果將是這樣的:
Score > 90 and < 100
M(student name) 92 (average score)
Score > 80 and < 90
P 86.8
I 83.4
Y 82.4
我還需要計算有多少范圍。 例如,對於上述結果,我們有兩個范圍:(>90 和 <100) 和 (>80 和 <90)。
我已經知道如何計算平均分數,但是我堅持將它們分組到范圍內並僅使用 LINQ 計算范圍數。
我想學習如何做。
您可以結合使用 LINQ 的Average
、 Select
和GroupBy
,以及一些算法:
var result = string.Join("\r\n",
students.Select(s =>
(s.Name, Average: s.Scores.Average(sc => (double)sc)))
.GroupBy(s => (int)Math.Ceiling(s.Average / 10))
.OrderByDescending(g => g.Key)
.Select(g =>
$"Score >= {g.Key * 10 - 10} and < {g.Key * 10}\r\n"
+ string.Join("\r\n", g.Select(s => $" {s.Name} {s.Average:F1}"))
);
或者略有不同
var result = string.Join("\r\n",
students.Select(s =>
(s.Name, Average: s.Scores.Average(sc => (double)sc)))
.GroupBy(s => (int)Math.Ceiling(s.Average / 10))
.OrderByDescending(g => g.Key)
.SelectMany(g =>
g.Select(s => $" {s.Name} {s.Average:F1}")
.Prepend($"Score >= {g.Key * 10 - 10} and < {g.Key * 10}\r\n"))
);
首先,請注意,您將需要一個平均分數剛好為 90 的案例。我假設這將由較高的存儲桶處理,但如果您需要較低的存儲桶,您可以更改邏輯。
最好按分數的“等級字母”計算和分組,因為它是一個字母,字母很容易按字母順序排列。
var studentsByGrade = students
.Select(x => new {
x.Name,
AvgScore = x.Scores.Average()
})
.GroupBy(x => GetGradeLetter(x.AvgScore));
這將使用輔助方法。
private static string GetGradeLetter(double score)
{
if (score is >= 90)
return "A";
if (score is >= 80)
return "B";
// add more as you'd like
return "ZZZ";
}
值得注意的是,您不需要在此處顯示字母 - 使用它只是因為它便於訂購,而且很可能這就是您最終會使用的。 通常,您會將低於“60”的任何事物標記為一組,因為(至少在美國學校系統中)這意味着“F”。
要顯示結果,請使用兩個 foreach。
foreach (var grade in studentsByGrade.OrderBy(x => x.Key))
{
foreach (var student in grade.OrderByDescending(x => x.AvgScore))
{
Console.WriteLine($"{student.Name} {student.AvgScore}");
}
Console.WriteLine();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.