简体   繁体   English

linq Except()方法出现意外行为

[英]Unexpected behavior with linq Except() method

class Program
{
    static void Main(string[] args)
    {
        List<string> aList = new List<string>();
        List<string> bList = new List<string>();
        List<string> answerList = new List<string>();
        aList.Add("and");
        aList.Add("and");
        aList.Add("AND");
        aList.Add("And");
        aList.Add("not");
        aList.Add("noT");
        bList.Add("NOt");
        answerList = aList.Except(bList, StringComparer.InvariantCultureIgnoreCase).ToList();

        foreach (var word in answerList)
        {
            Console.WriteLine(word);
        }
    }

The expected behavior of the above program is to remove all the occurrences of "not" in aList and return {and, and, AND, And}. 上述程序的预期行为是删除aList中出现的所有“not”并返回{and,and,AND,And}。 It seems "StringComparer.InvariantCultureIgnoreCase" has removed all the duplicates of the word "and" and returned just one occurrence of {and} in answerList. 似乎“StringComparer.InvariantCultureIgnoreCase”删除了单词“and”的所有重复项,并在answerList中只返回了一次{和}。

This is the result I intuitively would expect. 这是我直觉所期望的结果。

Except returns the set difference, and you explicitly state that you want case insensitive comparison to be used. 除了返回设置差异外,您明确声明要使用不区分大小写的比较。

From the documentation of Except() (emphasis mine): Except() (强调我的) 的文档

Produces the set difference of two sequences by using the default equality comparer to compare values. 通过使用默认的相等比较器来比较值,生成两个序列的集合差异

So, Except() returns a set , which means it returns each string at most once. 因此, Except()返回一个集合 ,这意味着它最多返回一次字符串。 And since you're telling it that case should be ignored, you're getting the output you're getting. 既然你告诉它应该忽略这个案例,你就得到了你得到的输出。

To work around that, use a method that doesn't operate on sets, like Where() : 要解决这个问题,请使用不对集合进行操作的方法,例如Where()

answerList = aList.Where(
    a => !blist.Contains(a, StringComparer.InvariantCultureIgnoreCase))
    .ToList();

This approach is slow (O( a · b )) when compared with Except() (O( a + b )), but that shouldn't be a problem for short sequences. Except() (O( a + b ))相比,这种方法很慢(O( a · b )),但对于短序列来说这不应该是一个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM