2013-03-25 47 views
3

有什么办法可以将以下代码缩减为Linq格式?将2个foreach循环缩减为linq查询

foreach (var current in currentWhiteListApps) 
{ 
    var exists = false; 

    foreach (var whiteList in clientSideWhiteLists) 
    { 
     if (current.appID.Equals(whiteList.appID)) 
     { 
      exists = true; 
     } 
    } 
    if (!exists) 
    { 
     deleteList.Add(current); 
    } 
} 

所有我能想到的是:

currentWhiteListApps.Select(x => { 
    var any = clientSideWhiteLists.Where(y => y.appID.Equals(x.appID)); 
    if (any.Any()) 
     deleteList.AddRange(any.ToArray()); 
    return x; 
}); 

理由LINQ
LINQ远比嵌套foreach循环更加易读,且需要更少的代码。所以这是我想它在LINQ

+0

为什么要在'LINQ'中使用这个特殊原因?它可能不会优化代码,并且会降低可读性。 – LukeHennerley 2013-03-25 11:41:29

+3

“LINQ规则#1”:除非您能够在3分钟内自行提供LINQ查询,否则不值得使用它。 :) – JleruOHeP 2013-03-25 11:42:18

+0

编辑到LINQ规则#1,如果你的职业....我不以任何方式塑造或形成Linq的专家,所以这条规则不适用。 – 2013-03-25 12:57:23

回答

2
var deleteList = currentWhiteListApps.Where(x => 
        clientSideWhiteLists.All(y => !x.appID.Equals(y.appID))) 
            .ToList(); 
+0

谢谢,看起来像一个体面的答案。 – 2013-03-25 12:59:12

1
var deleteList = currentWhiteListApps.Except(clientSideWhiteLists).ToList(); 

原因此解决方案假定两个集合包含相同类型的元素,并且该类型已重写equals()方法来比较的appid。

+0

+1:如果假设有效,则使用“Except”。否则,实现一个相等比较器并将其传递给'Except'。 – Henrik 2013-03-25 11:51:26

+0

这似乎是完美的。谢谢。 – 2013-03-25 13:01:43

+0

我在LINQPad上试过了,它不会产生其他答案和我的原始代码产生的结果。而我的代码产生了正确的答案。 – 2013-03-25 13:09:19

0
var validIds = new HashSet<int>(clientSideWhiteLists.Select(x => x.appId)); 
var deleteList = currentWhiteListApps.Where(x => !validIds.Contains(x.appId)).ToList(); 
+0

这是一个非常有趣的方式来做到这一点。我曾考虑过使用HashSet。尼斯:) – 2013-03-25 13:42:18