我有一个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))
}
答案 0 :(得分:2)
最佳学生
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
答案 1 :(得分:2)
使用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;
}
}
答案 2 :(得分: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;
答案 3 :(得分:0)
这样的东西?
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();