求林中平均值的最大值
本文关键字:最大值 平均值 林中 | 更新日期: 2023-09-27 17:59:19
我有一个List=new List();
public class Student
{
public string Id { get; set; }
public string name { get; set; }
public string subject { get; set; }
public string marks { get; set; }
}
我的目标
找到平均最高的学生
添加数据样本
i.Add(new List<Student> { Id=1,Name= "Maddy",Subject="English",Marks=87 };
i.Add(new List<Student> { Id=1,Name= "Maddy",Subject="Science",Marks=81 };
i.Add(new List<Student> { Id=2,Name= "Mathew",Subject="Maths",Marks=83 };
i.Add(new List<Student> { Id=2,Name= "Mathew",Subject="Science",Marks=80 };
我尝试了什么
var x= i.GroupBy(i=>i.Id)
.Select( g=> new
{
MaxAverage= g.Max(g.Average(i=>i.Marks))
}
-
使用Linq"查询语法"
var best = from student in students group student by student.Id into studentAverage let average = studentAverage.Average (s => s.Marks) orderby average descending select new { id = studentAverage.Key, average }; // change projection to have only id or average
-
使用Linq"方法语法"
var best = students .GroupBy (student => student.Id, student => student.Marks, (id, marks) => new { id, average = marks.Average () }) .OrderByDescending (studentAverage => studentAverage.average) // add a projection (Select) here to have only id or average .FirstOrDefault ();
也许更简单的替代方案,但更倾向于只获得Id
var best = students .ToLookup (s => s.Id, s => s.Marks) .OrderByDescending (marksById => marksById.Average ()) .FirstOrDefault (); // Key will contain the Id but Average must be calculated again // var avg = best.Average();
-
使用"经典"代码(较长但更清晰的步骤)
var studentMarks = new Dictionary<int, List<double>> (students.Count); foreach (var student in students) { int id = student.Id; List<double> marks; if (!studentMarks.TryGetValue (id, out marks)) { marks = new List<double> (); studentMarks.Add (id, marks); } marks.Add (student.Marks); } double? bestAverage = null; int? idOfBest = null; foreach (var idAndMarks in studentMarks) { var average = 0.0; foreach (var mark in idAndMarks.Value) { average += mark; } average /= idAndMarks.Value.Count; if (average > bestAverage) { bestAverage = average; idOfBest = idAndMarks.Key; } }
最佳学生
var best = i.GroupBy(g => g.Id)
.Select(g => new {
StudentID = g.Key,
Name = g.First().Name,
Average = g.Average(m => m.Marks),
})
.OrderByDescending(g => g.Average)
.First();
// best = { StudentID = 1, Name = Maddy, Average = 84 }
最佳平均
var best = i.GroupBy(g => g.Id)
.Select(g => g.Average(m => m.Marks))
.Max();
// best = 84.0
查询语法(只是因为)
var best = (from student in
from grade in grades
group grade by grade.Id
select student.Average(mark=>mark.Marks)).Max();
// best = 84.0
没有LINQ(我看到一条评论建议你这样做…哎哟)
var dict = new Dictionary<int, List<double>>();
foreach (var g in i )
{
var id = g.Id;
if (!dict.ContainsKey(id))
dict.Add(id, new List<double>());
dict[id].Add(g.Marks);
}
double best = 0.0;
foreach (var g in dict)
{
var totalmarks = 0.0;
foreach (var mark in g.Value)
{
totalmarks += (double)mark;
}
var average = totalmarks / g.Value.Count;
if (best < average)
best = average;
}
// best = 84.0
没有LINQ(稍微优化)
var dict = new Dictionary<int, Tuple<int, double>>();
foreach (var g in i)
{
var id = g.Id;
Tuple<int, double> t;
if (!dict.ContainsKey(id))
dict.Add(id, t = Tuple.Create(0, 0.0));
else
t = dict[id];
var c = t.Item1 + 1;
dict[id] = Tuple.Create(c, (t.Item2 * t.Item1 + g.Marks) / c);
}
double best = 0.0;
foreach (var g in dict)
{
var m = g.Value.Item2;
if (best < m)
best = m;
}
// best = 84.0
var i = new List<Student>();
i.Add(new Student { Id = 1, Name = "Maddy", Subject = "English", Marks = 87 });
i.Add(new Student { Id = 1, Name = "Maddy", Subject = "Science", Marks = 81 });
i.Add(new Student { Id = 2, Name = "Mathew", Subject = "Maths", Marks = 83 });
i.Add(new Student { Id = 2, Name = "Mathew", Subject = "Science", Marks = 80 });
var students = i.GroupBy(p => p.Id).ToDictionary(group => group.Key, group => group.Select(p => p.Marks).Average());
var maxStudent = students.Aggregate((l, r) => l.Value > r.Value ? l : r).Key;
类似的东西?
var bestStudent = i.GroupBy(i=>i.Id)
.Select( g=> new Student
{
Id = g.Key,
Name = g.First().Name,
Marks = g.Average(i=>i.Marks))
})
.OrderByDescending(s => s.Marks)
.FirstOrDefault();