1

I'm working on a windows form application which purpose is to calculate and display Salary statistics stored on a textfile.

I'm having a problem with one task right now: Calculate which profession who has the highest average current salary.

I have stored every salary statistics as SalaryInformation objects. I'll show you how the SalaryInformation class looks like:

public sealed class SalaryInformation
{
    private string profession;
    private int yearOfEmployment;
    private decimal startSalary;
    private decimal currentSalary;

    public string Profession
    {
        get { return profession; }
        set { profession = value; }
    }

    public int YearOfEmployment
    {
        get { return yearOfEmployment; }
        set { yearOfEmployment = value; }
    }

    public decimal StartSalary
    {
        get { return startSalary; }
        set { startSalary = value; }
    }


    public decimal CurrentSalary
    {
        get { return currentSalary; }
        set { currentSalary = value; }
    }

    public SalaryInformation()
    { }

    public SalaryInformation(string p, int yoe, decimal startS, decimal currentS)
    {
        profession = p;
        yearOfEmployment = yoe;
        startSalary = startS;
        currentSalary = currentS;
    }

What I want to do is to return a single string. The profession property of a SalaryInformation object which is associated with the highest average currentSalary. Bear in mind that there a several SalaryInformation objects who have common profession value (For example, three SalaryInformation objects have the value "doctor" on the property profession).

I started with this method, and I got stuck here:

 public string GetHighestPaidProfession()
    {
        string highestPaidProfession = "";

        //Gets all the salaryInformation objects and stores them in a list
        List<SalaryInformation> allSalaries = new List<SalaryInformation>();
        allSalaries = data.GetSalaryInformation();          


        //Right here I don't know how to do the rest from here.
        //I realize that I have to calculate the average currentsalary from every
        //SalaryInformation I got in the list allSalaries. But then I have to
        //to get the actual profession which has the highest average currentsalary
        //among them. It's right there I get stuck.

        return highestPaidProfession;
    }

If you need more code and details, just let me know and I'll add it to this thread.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Assassin87
  • 285
  • 3
  • 7
  • 15
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Jul 01 '13 at 20:53
  • possible duplicate of [How to use LINQ to select object with minimum or maximum property value](http://stackoverflow.com/questions/914109/how-to-use-linq-to-select-object-with-minimum-or-maximum-property-value) - You're looking for `AverageBy()`, instead of `MinBy()` or `MaxBy()` but the logic is the same. – Bobson Jul 01 '13 at 21:27

5 Answers5

2

Try using LINQ:

return allSalaries.GroupBy(s => s.Profession)
                  .OrderByDescending(g => g.Average(n => n.CurrentSalary))
                  .FirstOrDefault().Key;

This should do the trick.

It'sNotALie.
  • 22,289
  • 12
  • 68
  • 103
0

Try this.

void Main()
{
    var allSalaries = new List<SalaryInformation> {
    new SalaryInformation("doctor", 1, 100, 120), 
    new SalaryInformation("doctor", 1, 120, 150), 
    new SalaryInformation("engineer", 1, 50, 100)};

    var profession = allSalaries.GroupBy (s => s.Profession)
    .Select (s => new {Profession = s.Key, SalaryAvg = s.Average (x => x.CurrentSalary)})
    .OrderByDescending (g => g.SalaryAvg)
    .FirstOrDefault().Profession;

    Console.WriteLine(profession);
}

public class SalaryInformation
{
    private string profession;
    private int yearOfEmployment;
    private decimal startSalary;
    private decimal currentSalary;

    public string Profession
    {
        get { return profession; }
        set { profession = value; }
    }

    public int YearOfEmployment
    {
        get { return yearOfEmployment; }
        set { yearOfEmployment = value; }
    }

    public decimal StartSalary
    {
        get { return startSalary; }
        set { startSalary = value; }
    }


    public decimal CurrentSalary
    {
        get { return currentSalary; }
        set { currentSalary = value; }
    }

    public SalaryInformation()
    { }

    public SalaryInformation(string p, int yoe, decimal startS, decimal currentS)
    {
        profession = p;
        yearOfEmployment = yoe;
        startSalary = startS;
        currentSalary = currentS;
    }
}
Vlad Bezden
  • 83,883
  • 25
  • 248
  • 179
0

Try following (using Linq)

 allSalaries = data.GetSalaryInformation(); 
 var allSalariesByProfession = allSalaries.GroupBy(x=>x.Profession);
 var averageSalariesByProfession = allSalariesByProfession.Select(group => new {Profession = group.Key, Avg=group.Average(item=>item.CurrentSalary));
 var highestPayingprofession = averageSalariesByProfession.OrderByDescending(x=>x.Avg).First().Key;
Tilak
  • 30,108
  • 19
  • 83
  • 131
0
allSalaries = data.GetSalaryInformation(); 

var averageCurrentSalaries = allSalaries.GroupBy(
    si => si.Profession, 
    si => si, 
    (key, g) => new 
    { 
         Profession = key, 
         AverageCurrentSalary = g.Average(si => si.CurrentSalary);
    });

var highestPaidProfession = averageCurrentSalaries.OrderByDescending(
    as => as.AverageCurrentSalary).First().Profession;
devdigital
  • 34,151
  • 9
  • 98
  • 120
0

This will get you the highest paid profession(the average of salaries)

        public string GetHighestPaidProfession()
        {
            //string highestPaidProfession = ""; no need for the string variable.

            //Gets all the salaryInformation objects and stores them in a list
            //just added this elements to list for demonstration only.
            List<SalaryInformation> allSalaries = new List<SalaryInformation>()
            {
                new SalaryInformation("doctor",2010,500.00m,585.00m),
                new SalaryInformation("doctor",2010,500.00m,585.00m),
                new SalaryInformation("doctor",2010,500.00m,550.00m),
                new SalaryInformation("doctor",2010,500.00m,550.00m),
                new SalaryInformation("manager",2010,400.00m,510.00m),
                new SalaryInformation("manager",2010,400.00m,490.00m),
                new SalaryInformation("manager",2010,400.00m,500.00m),
                new SalaryInformation("manager",2010,400.00m,480.00m),
                new SalaryInformation("director",2010,600.00m,625.00m),
                new SalaryInformation("director",2010,600.00m,615.00m)
            };

            Dictionary<string,List<decimal>> results = new Dictionary<string,List<decimal>>();

            foreach(SalaryInformation si in allSalaries)
            {
                if(results.ContainsKey(si.Profession))
                {
                    results[si.Profession].Add(si.CurrentSalary);
                }
                else
                {
                    results.Add(si.Profession,new List<decimal>(){si.CurrentSalary});
                }
            }

            //this will result in dictionary<string,decimal>,where the dedimal will
            //already be the average of all salary of each profession.
            var result = results.ToDictionary(k => k.Key, v => v.Value.Sum() / v.Value.Count);

            //returns the string in result dictionary which points to the
            //highest value.
            return result.Aggregate((l, r) => l.Value > r.Value ? l : r).Key;
        }
terrybozzio
  • 4,424
  • 1
  • 19
  • 25