Unicornese
Unicornese

Reputation: 135

Get Highest Average for numbers in a List

In my WCF interface I have a class definition of

[DataContract]
public class Student
{
    [DataMember]
    public int Sid { get; set;}
    [DataMember]
    public string StudentName { get; set;}
    [DataMember]
    public int M1 { get; set;}
    [DataMember]
    public int M2 { get; set; }
    [DataMember]
    public int M3 { get; set; }
}

and I have this method

     [OperationContract]
     Student GetTopper(List<Student> LS);

The method above should collect a List of type of <Student>, calculate the average of M1, M2 and M3 for each student and return the Student with the highest average.

This is what the implementation i currently have of the GetTopper method looks like

   public Student GetTopper(List<Student> LS)
        {
        foreach (Student s in LS)
        {
            double Avg = (s.M1 + s.M2 + s.M3) / 3.0;

        }   
    }

How can I implement this using the GetTopper class? That is passing a list of students, calculate their average scores and return the Student with the highest average. Thanks

Upvotes: 1

Views: 404

Answers (3)

Leonid Malyshev
Leonid Malyshev

Reputation: 475

public Student GetTopper(List<Student> LS)
{
    return LS.FirstOrDefault(s => ((s.M1 + s.M2 + s.M3) / 3.0).Equals(LS.Max(m => (m.M1 + m.M2 + m.M3) / 3.0)));
}

Upvotes: 0

Eric
Eric

Reputation: 5733

You can use order by desc then get the first one by linq

public Student GetTopper(List<Student> LS)
{
    if(LS == null) return null;
    return LS.OrderByDescending(s => (s.M1 + s.M2 + s.M3) / 3.0).FirstOrDefault();
}

Edit

The / 3.0 should be redundant, it is the same to determine top student by the highest sum of score or highest average of score. Credit to Dmitry Bychenko's answer.

Upvotes: 6

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

You're looking for arg max implementation; there's no need for sorting, a simple foreach loop will do:

public Student GetTopper(IEnumerable<Student> value) {
  if (null == value)
    throw new ArgumentNullException("value");

  boolean first = true;
  Student result = null;
  double maxValue = double.NegativeInfinity;

  foreach (var item in value) {
    if (null == item)
      continue;

    // there's no need to divide by 3, providing that M1, M2, M3
    // are small enough not to trigger integer overflow
    if (first || item.M1 + item.M2 + item.M3 > maxValue) {
      first = false;
      maxValue = item.M1 + item.M2 + item.M3;
      result = item;   
    }
  }

  return result; 
}

Upvotes: 4

Related Questions