C# 如何根据ID从员工薪资第二高的员工集合中选择具有LINQ的不同员工?
看看下面的例子。这里的雇员ID=2,也就是史蒂夫有3个副本。 我只想要每个ID的一个记录。我想要选择薪水第二高的记录。因此,在史蒂夫的情况下,选择将是两个有160个作为工资的史蒂文之一C# 如何根据ID从员工薪资第二高的员工集合中选择具有LINQ的不同员工?,c#,.net,linq,C#,.net,Linq,看看下面的例子。这里的雇员ID=2,也就是史蒂夫有3个副本。 我只想要每个ID的一个记录。我想要选择薪水第二高的记录。因此,在史蒂夫的情况下,选择将是两个有160个作为工资的史蒂文之一 public class Employee { public int ID { get; set; } public string Name { get; set; } public int Salary { g
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
public static List<Employee> GetAllEmployees()
{
return new List<Employee>()
{
new Employee { ID = 1, Name = "Mark", Salary = 100 },
new Employee { ID = 2, Name = "Steve", Salary = 150 },
new Employee { ID = 2, Name = "Steve", Salary = 160 },
new Employee { ID = 2, Name = "Steve", Salary = 160 },
new Employee { ID = 2, Name = "Steve", Salary = 165 },
new Employee { ID = 3, Name = "Ben", Salary = 140 }
};
}
}
我知道如何根据属性获取不同的记录:
var result = Employee.GetAllEmployees().GroupBy(x=>x.ID).Distinct();
但另一方面我迷路了
请注意,我只寻找LINQ lambda/扩展语法答案。谢谢 一种方法是在GroupBy之后使用Select。这会将每个组转换为一名员工
Employee.GetAllEmployees().GroupBy(x=>x.ID).Select(x => FindSecondHighest(x));
其中FindSecondHighest应该如下所示:
private static Employee FindSecondHighest(IEnumerable<Employee> employees) {
var list = employees.ToList();
if (list.Count == 1) { return list[0]; }
return list.OrderByDescending(x => x.Salary).Skip(1).First();
}
首先,失去明确的目标。根据定义,分组是唯一的
根据您的要求,您需要按薪资降序排列分组结果,然后选择第二个。仅当分组包含多个项时才执行此操作。因此,这应该是可行的:
var result = Employee.GetAllEmployees()
.GroupBy(x => x.ID)
.Select(x => (x.Count() > 1 ? x.GroupBy(y => y.Salary).Skip(1).Select(y => y.First()) : x).First()
);
Employee.GetAllEmployees().Where(x => {
recordsWithID = Employee.GetAllEmployees().Where(y => y.ID == x.ID).OrderByDescending(y => y.Salary);
recordToReturn = recordsWithID.Count > 1 ? recordsWithID.Skip(1).First() : recordsWithID.First();
return x.ID == recordToReturn.ID;
});
编辑:根据评论更新了我的答案,我们需要按薪资分组,然后跳过1,以缓解第二条记录也具有最高薪资值的情况。以下操作应该有效:
var result = Employee.GetAllEmployees()
.GroupBy(x => x.ID)
.Select(x => (x.Count() > 1 ? x.GroupBy(y => y.Salary).Skip(1).Select(y => y.First()) : x).First()
);
Employee.GetAllEmployees().Where(x => {
recordsWithID = Employee.GetAllEmployees().Where(y => y.ID == x.ID).OrderByDescending(y => y.Salary);
recordToReturn = recordsWithID.Count > 1 ? recordsWithID.Skip(1).First() : recordsWithID.First();
return x.ID == recordToReturn.ID;
});
首先,在主谓词中,我们选择具有x ID的所有用户。然后,如果有多个具有该ID的记录,我们将获得工资第二高的记录,否则,我们只选择具有该ID的唯一记录。然后,如果对于x的ID组,x是实际需要的记录,因此x是唯一一个ID为的记录,或者x是ID为x的记录中工资第二高的记录,返回x,否则返回x
我目前无法测试这一点,因为我没有在电脑前,但这会给你一个想法。你可以使用.GroupBy和.Select尝试类似的方法:
如果组计数为1,则不需要排序。返回X您如何保证第二个记录也有第二个最高工资?因为它可能与第一条记录具有相同的值。捕捉得好。一种方法是按工资分组,然后跳过1。请看我的最新答案。谢谢。你的答案肯定更具可读性,但我已经标记了杰罗恩的答案,因为他是第一个回答正确的人。
static void Main(string[] args)
{
List<Employee> secondHighestSalaryPersons = Employee.GetAllEmployees()
.GroupBy(x => x.Name)
.Select(x =>
{
var group = x.ToList();
if (group.Count > 1)
return group.OrderByDescending(y => y.Salary).Skip(1).FirstOrDefault();
else
return group.FirstOrDefault();
})
.ToList();
}