如果我有以下型号:
Public class Person {
public string Name {get; set;}
public string Type {get; set;}
public int Salary {get; set;}
}
我有一个人员列表,List<Person> persons = new List<Person>();
现在我想要最常见的经理薪水,如果不存在,我想要最常见的MiddleManagers工资。
我尝试了以下内容:
int salary= persons.Where(x => x.Type=="Manager" || x.Type=="MiddleManager")
.GroupBy(pr => pr.Salary)
.OrderByDescending(g => g.Count())
.Select(x => x.Key)
.FirstOrDefault();
但是这将返回经理和MiddleManagers中最常见的薪水,有没有办法实现上述目标而不去:
int salary= persons.Where(x => x.Type=="Manager")
.GroupBy(pr => pr.Salary)
.OrderByDescending(g => g.Count())
.Select(x => x.Key)
.FirstOrDefault();
if(salary==0)
salary= persons.Where(x => x.Type=="MiddleManager")
.GroupBy(pr => pr.Salary)
.OrderByDescending(g => g.Count())
.Select(x => x.Key)
.FirstOrDefault();
为什么我要避免上述情况?因为我对很多属性都有相同的逻辑。
答案 0 :(得分:3)
使用C#本地函数:
ILookup<string, Person> personsByType = persons.ToLookup(person => person.Type);
double getSalary(string type)
{
return personsByType[type]
.GroupBy(pr => pr.Salary)
.OrderByDescending(g => g.Count())
.Select(x => x.Key)
.FirstOrDefault();
}
double salary= getSalary("Manager");
if (salary == 0)
{
salary = getSalary("MiddleManager");
}
请注意,如果只有在没有特定类型的人的情况下才获得0薪水,因为我认为某人不能拥有0薪水。所以你可以这样做:
double? getSalary(string type)
{
IEnumerable<Person> selectedPeople = personsByType[type];
return selectedPeople.Any() ? selectedPeople
.GroupBy(pr => pr.Salary)
.OrderByDescending(g => g.Count())
.Select(x => x.Key)
.First()
: null;
}
double? salary= getSalary("Manager");
if (!salary.HasValue)
{
salary = getSalary("MiddleManager");
}
答案 1 :(得分:2)
您可以检查是否存在与第一个条件匹配的Any项,并将Type
分配给将在查询中使用的字符串变量:
string property = persons.Any(x => x.Type == "Manager") ? "Manager" : "MiddleManager";
int salary = persons.Where(x => x.Type == property)
.GroupBy(pr => pr.Salary)
.OrderByDescending(g => g.Count())
.Select(x => x.Key)
.FirstOrDefault();
List<Person>
中确切的分组逻辑的一半通用方法可能如下所示:
public int mostCommonSalary(List<Person> collection, params string [] types)
{
foreach (var type in types)
{
if (collection.Any(x => x.Type == type))
{
return collection.Where(x => x.Type == type)
.GroupBy(pr => pr.Salary)
.OrderByDescending(g => g.Count())
.Select(x => x.Key)
.FirstOrDefault();
}
}
// nothing found
return -1;
}
您可以根据需要使用多种类型。它的第一场比赛将被退回:
int salary = mostCommonSalary(persons, "Manager", "MiddleManager", "MicroManager", "NanoManager");
通过传递您想要过滤的属性,您可以使它更通用或更通用:
public int mostCommonSalaryGeneral<T>(List<Person> collection,
Func<Person, T> filterFunc, params T[] types)
{
foreach (var type in types)
{
if (collection.Any(x=> filterFunc(x).Equals(type)))
{
return collection.Where(x=> filterFunc(x).Equals(type))
.GroupBy(pr => pr.Salary)
.OrderByDescending(g => g.Count())
.Select(x => x.Key)
.FirstOrDefault();
}
}
// nothing found
return -1;
}
通过这种方式,您可以按所选属性进行过滤,并调用以下方法:
int salary = mostCommonSalaryGeneral(persons, p => p.Type, "Manager", "MiddleManager", "MicroManager", "NanoManager");
int salary = mostCommonSalaryGeneral(persons, p => p.Name, "Max", "Maxine", "Masud");
int salary = mostCommonSalaryGeneral(persons, p => p.SomeID, 1234, 3456);
答案 2 :(得分:1)
使用2种类型的简单循环,在循环体中使用Linq查询,或围绕Linq查询构建函数并使用不同类型调用它。例如:
var salary = GetSalary(persons, "Manager");
if (salary == 0) salary = GetSalary(persons, "MiddleManager");