In this article, we will find the N-th highest salary of employee using LINQ/Lambda.
Introduction
It is a very common question in many interview (in SQL Server parlance) to find the N-th highest salary of Employees.But recently, I came across to do the same using LINQ and also to handle ties.This article will speak about that.
Straight to Experiment
Let us first make the environment.First let us declare an Employee class
class Employee
{
public string EmpName { get; set; }
public int Salary { get; set; }
}
Then populate some records to it
private static List<employee> GetEmpRecord()
{
List<employee> empCollection = new List<employee>();
empCollection.Add(new Employee { EmpName = "Emp1", Salary = 10000 });
empCollection.Add(new Employee { EmpName = "Emp2", Salary = 3456 });
empCollection.Add(new Employee { EmpName = "Emp3", Salary = 14256 });
empCollection.Add(new Employee { EmpName = "Emp4", Salary = 15000 });
empCollection.Add(new Employee { EmpName = "Emp5", Salary = 10000 });
empCollection.Add(new Employee { EmpName = "Emp6", Salary = 6000 });
empCollection.Add(new Employee { EmpName = "Emp7", Salary = 2000 });
empCollection.Add(new Employee { EmpName = "Emp8", Salary = 5000 });
empCollection.Add(new Employee { EmpName = "Emp9", Salary = 7000 });
empCollection.Add(new Employee { EmpName = "Emp10", Salary = 7000 });
return empCollection;
}
Finally let us write the program
var empCollection = GetEmpRecord();
var employees = (from emp in empCollection
group emp by emp.Salary into g
orderby g.Key descending
select new
{
EmpRecord = g.ToList()
}).ToList();
Let us analyze the program. First we are grouping up the Employee Record Set by their salary.
var employees = (from emp in empCollection
group emp by emp.Salary into g
select new
{
EmpRecord = g.ToList()
}).ToList();
If we put a break point there and check , we will find that there are a total of 8 elements since both Emp1 and Emp5 are earning 10000 while Emp9 and Emp10 are earning 7000 each.But it is not sorted. Inorder to sort the record set, we have introduce the order by clause that will guarenteed to bring teh result in a sorted order.
Finally we are projecting the record using the select statement.At this stage we will get the count as 8 only but with sorted record set.
Suppose we want to find out the third highest salary which should be "Emp1" and "Emp5" (both earning 10000 each). The first will be "Emp4" with 15000 and second is "Emp3" with Salary = 14256.
Since it is a collection, we can use index as shown under to obtain the desired result.
var result = employees[2];
will give the desire result.
The final program will be
var empCollection = GetEmpRecord();
int whichEmpSalary = 3;
var employees = (from emp in empCollection
group emp by emp.Salary into g
orderby g.Key descending
select new
{
EmpRecord = g.ToList()
}).ToList();
employees[whichEmpSalary - 1].EmpRecord
.ForEach(i => Console.WriteLine("Emp Name {0} earns {1}", i.EmpName, i.Salary));
Console.ReadKey();
Output
Emp Name Emp1 earns 10000
Emp Name Emp5 earns 10000
A lambda version will be as under
//Lambda version
empCollection
.GroupBy(g=>g.Salary)
.OrderByDescending(o=>o.Key)
.Select(s=>new{EmpRecord = s.ToList()})
.ToList()[whichEmpSalary - 1].EmpRecord
.ForEach(i => Console.WriteLine("Emp Name {0} earns {1}", i.EmpName, i.Salary));
Conclusion
I think that this article will be a good aid.Thanks for reading.