不同字段上的多个LINQ聚合函数适用于整个集合

时间:2011-09-20 18:06:43

标签: linq

有人可以通过一些提示帮助我。基本上我想在不同的字段上应用不同的聚合函数(Count,Sum,Min)到整个集合(不是真正的灌浆),并将结果作为字段以匿名类型返回。 类似的东西:

var employees = new[] {
    new { Name = "John Smith", Gender="M", DateOfHiring=new DateTime(2004, 10, 22), Salary=60000 },
    new { Name = "Jane Smith", Gender="F", DateOfHiring=new DateTime(2008, 5, 22), Salary=55000 },
    new { Name = "Kathleen Smith", Gender="F", DateOfHiring=new DateTime(2006, 10, 22), Salary=75000 },
    new { Name = "David Smith", Gender="M", DateOfHiring=new DateTime(2002, 7, 12), Salary=85000 },
    new { Name = "Mary Smith", Gender="F", DateOfHiring=new DateTime(2009, 6, 15), Salary=55000 }
};

var query = from e in employees
             select new {
                NumberOfMaleEmployees = /* Count Where Gender = 'M' */,
                NumberOfFemaleEmployees = /* Count Where Gender = 'F' */,
                TotalSalaries = /* Sum All */,
                AverageSalary = /* Avg All */,
                LatestEmployee = /* Employee with Min DateOfHiring */
             };

是否可以在一个查询中实现此目的? 提前致谢 尤利安

2 个答案:

答案 0 :(得分:2)

虽然Skeet先生的回答有效,但确实会导致employees重复5次(包括“最新员工”)。你可能最好使用跟踪每个for循环的int maleCount = 0; int femaleCount = 0; long totalSalary = 0; double averageSalary = 0.0; object latestEmployee = null; for (int i = 0; i < employees.Length; i++) { maleCount += (employees[i].Gender == "M") ? 1 : 0; totalSalary += employees[i].Salary; if (latestEmployee == null || employees[i].HireDate > latestEmployee.HireDate) { latestEmployee = employees[i]; } } femaleCount = employees.Length - maleCount; averageSalary = totalSalary / (double)employees.Length; 循环利益集合:

{{1}}

我认为员工可以是男性或女性;如果不保证这个假设,你需要调整你的代码。

答案 1 :(得分:1)

您不希望迭代数组以从它的外观开始 - 您只是想要:

var query = new {
    NumberOfMaleEmployees = employees.Count(x => x.Gender == "M"),
    NumberOfFemaleEmployees = employees.Count(x => x.Gender == "F"),
    TotalSalaries = employees.Sum(x => x.Salary),
    AverageSalary = employees.Average(x => x.Average),
};

“最新员工”位有点棘手 - 你基本上想要来自MaxByMoreLINQ,这会让你写下来:

LatestEmployee = employees.MaxBy(x => x.DateOfHiring)

(当然,您可以包含在上述查询中)。