2013-03-25 102 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