2016-09-22 175 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