4

没有性能损失的最佳 LINQ 方法是什么?我们如何使用 LINQ 只迭代列表一次来做同样的事情?

class Employee  
{  
    string name ...;  
    string age .....;  
    int empType ...;  
    int income ...;  
}  

List<Employee> myList ...;  
List<Employee> toList...;  
int totalIncomeOfToList = 0;  

foreach(Employee emp in myList)  
{  
    if(emp.empType == 1)  
    {  
        toList.Add(emp);  
        totalIncomeOfToList += emp.income;  
    }  
}  
4

3 回答 3

13

(我假设您也想要过滤列表 - 到目前为止给出的其他答案仅以总和结尾,而不是列表。如果您不需要列表,它们绝对没问题,但它们是不等同于您的原始代码。)

好吧,您可以只对原始列表进行一次迭代——然后再对过滤后的列表进行迭代:

var toList = myList.Where(e => e.empType == 1).ToList();
var totalIncomeOfToList = toList.Sum(e => e.income);

诚然,就两次通过处理器缓存而言,这可能会降低效率,但如果它很重要,我会感到惊讶。如果你能证明它重要,你总是可以回到“手动”版本。

可以编写一个带有副作用的投影,一次完成所有操作,但这太难看了,除非我真的迫于压力,否则我什至不会将其包含在答案中。

于 2013-10-22T14:43:52.720 回答
1

我知道 LINQ 不应该有副作用,但它的价值...

int totalIncomeOfToList = 0;  
List<Employee> toList = myList
    .Where(emp => emp.empType == 1)
    .Select(emp => { totalIncomeOfToList += emp.income; return emp; })
    .ToList();
于 2013-10-22T14:50:34.393 回答
1

试试这个以获得总收入

var totalIncomeOfToList = myList.Where(e => e.empType == 1).Sum(e => e.income);

如果您还想要过滤员工的列表,那么:

var toList = myList.Where(e => e.empType == 1).ToList();
var totalIncomeOfToList = toList.Sum(e => e.income);

使用 foreach 性能会稍好一些,但这样代码会更加清晰和精确。

于 2013-10-22T14:42:53.750 回答