2016-09-22 147 views
1

我無法理解linq任何運算符。讓我們考慮下面的代碼片段(使用VS 2010和.NET 4.0)linq任何運算符不等於(!=)

List<string> sample = new List<string> { "a", "b", "c", "d" }; 
List<string> secondSample = new List<string> { "b", "c" }; 

foreach (string s in sample) 
{ 
    if(secondSample.Any(data=> data.ToString() == s)) 
     Console.WriteLine(s); 
} 

當運行它產生以下輸出

b 
c 

這是我很期待。但是,如果我改變等號(==)以不相等(!=)我得到這個

a 
b 
c 
d 

不應該這個是

a 
d 

如果我改變了,如果條件

if(!(secondSample.Any(data=> data.ToString() == s))) 

我得到

a 
d 

所以我的問題是我是否以錯誤的方式解釋Any運算符?不應

if(secondSample.Any(data=> data.ToString() != s)) 

評價爲真時,從secondSample值是不是在樣品

回答

4

如果你想使用=操作符,你希望a d的結果,那麼你應該使用AllAny

if(secondSample.All(data=> data.ToString() != s)) 
      Console.WriteLine(s); 

說明secondSample.Any(data=> data.ToString() != s)將是真實的,如果在secondSample只有一個元素不等於到給定的數據項(在您的sample列表中),所以在您的情況下,它將始終爲真,並且您看到所有元素都寫在控制檯中。

更好的解決方案具有兩個陣列A和B,如果要那些使用LINQ可以可以嘗試Except,如果你正在尋找共同的元件可能會嘗試Intersect其不是在B A元素:

List<string> A = new List<string> { "a", "b", "c", "d" }; 
List<string> B= new List<string> { "b", "c" }; 

var AnotInB = A.Except(B).ToList(); //a, d 

var AInB = A.Intersect(B).ToList(); //b, c 
+0

降頻選民考慮留下評論和解釋。 –

0

這一切,沒有任何當你改變!=

if(secondSample.All(data=> (data.ToString() != s))) 
當你否定一個表達式內部

或成爲和:「A或B」的否定變成「不是A而不是B」。

1

任何操作符都可以問'在回答謂詞的集合中是否有任何元素'。在你的情況下,它是存在的,所以它是正確的輸出。

2

!= in an Any意味着ALL不相等。

所以你看,如果有任何不相等的,那麼你可以打印。 猜猜看,你總是有至少1個不相等的東西。這就是你得到所有答案的原因。

在你說的其他陳述中:不平等的你可以打印...

有什麼更清晰的?

+0

你的解釋也很好。簡明扼要。我只能標記一個作爲答案。否則,我會同時標記 – Muhid

0

以下是微軟Any源代碼實現,檢查here

public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { 
      if (source == null) throw Error.ArgumentNull("source"); 
      if (predicate == null) throw Error.ArgumentNull("predicate"); 
      foreach (TSource element in source) { 
       if (predicate(element)) return true; 
      } 
      return false; 
     } 

現在,在你所提供的情況並不適用:

source - List<string> secondSample = new List<string> { "b", "c" }; 

Predicate - List<string> sample = new List<string> { "a", "b", "c", "d" }; 

在第一種情況下,當你使用==,然後它是遍歷整個集合(source),直到它可以得到的點match,這是正確的存在和結果打印

在第二種情況下,當您申請!=時,它可以獲得匹配的每個案件,"a", "b", "c", "d",它不存在,因此是真實的,並打印所有內容。

爲什麼除了在這種情況下工作:

var result = sample.Except(secondSample); 

以下是實現,事實上用set,副本將自動刪除

public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) 
     { 
      if (first == null) throw Error.ArgumentNull("first"); 
      if (second == null) throw Error.ArgumentNull("second"); 
      return ExceptIterator<TSource>(first, second, null); 
     } 

static IEnumerable<TSource> ExceptIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer) { 
      Set<TSource> set = new Set<TSource>(comparer); 
      foreach (TSource element in second) set.Add(element); 
      foreach (TSource element in first) 
       if (set.Add(element)) yield return element; 
     } 
1

使用存在

List<string> sample = new List<string> { "a", "b", "c", "d" }; 

List<string> secondSample = new List<string> { "b", "c" }; 

foreach (string s in sample) 
     {   
      if (!secondSample.Exists(data => data.ToString() == s))    
       Console.WriteLine(s); 
     } 
+0

如果你解釋爲什麼Any操作員是錯誤的選擇,你的答案會更好。 – Daz