返回基于C#中另一个列表过滤的列表

Nic*_*ick 2 c# linq

我是C#的新手,所以试图测试一个简单的字符串过滤器,但没有得到所需的结果.这是我的测试方法:

[TestMethod]
    public void Test_ExceptFilter()
    {
        IEnumerable<string> allnames = new List<string>(){"Thumbs.db","~","one","two exe here","three"};
        var u = FileLister.GetFilteredList(allnames, new [] { "thumbs","~"}, false);
    }
Run Code Online (Sandbox Code Playgroud)

我有一个称为静态类FileLister它具有GetFilteredList方法,并且不工作的位是当我试图返回不包含在第二IEnumerable的任何字符串列表.

所以在我的例子里,我希望var你只有"one","这里有两个exe"和"three",但它拥有allnames列表中的所有项目!

这些是我尝试过的各种方式,在所有这些方面,我努力的部分是布尔包含词作为false传入的地方:

//Return strings that contain or dont contain any element in the array
    public static IEnumerable<string> GetFilteredList(IEnumerable<string> myfiles,
        IEnumerable<string> filterbythesewords, bool includewords)
    {
        if (includewords)
        {
            return from line in myfiles
                where filterbythesewords.Any(item => line.Contains(item))
                select line;
        }
        else
        {

            return from line in myfiles
                where filterbythesewords.Any(item => !line.Contains(item))
                select line;


        }
    }
Run Code Online (Sandbox Code Playgroud)

第二次试验

 //Return strings that contain or dont contain any element in the array
    public static IEnumerable<string> GetFilteredList(IEnumerable<string> myfiles,
        IEnumerable<string> filterbythesewords, bool includewords)
    {
        if (includewords)
        {
            return from line in myfiles
                where filterbythesewords.Any(item => line.Contains(item))
                select line;
        }
        else
        {

            List<string> p = new List<string>();
            p.AddRange(myfiles.Except(filterbythesewords));
            return p;


        }
    }
Run Code Online (Sandbox Code Playgroud)

第三次试验

 //Return strings that contain or dont contain any element in the array
    public static IEnumerable<string> GetFilteredList(IEnumerable<string> myfiles,
        IEnumerable<string> filterbythesewords, bool includewords)
    {
        if (includewords)
        {
            return from line in myfiles
                where filterbythesewords.Any(item => line.Contains(item))
                select line;
        }
        else
        {
           return myfiles.Where(file => filterbythesewords.Any(x => !file.ToUpperInvariant().Contains(x.ToUpperInvariant())));
        }
    }
Run Code Online (Sandbox Code Playgroud)

我怎么能让这个工作好吗?最终,我希望能够根据文件扩展名或部分名称从目录列表中过滤文件名.

干杯

Jon*_*eet 10

问题是您使用Any的是负面条件 - 这意味着如果候选中没有任何单词,您将包含该值.相反,你想把它想象成:

  • 如果文件包含任何单词,则排除文件
  • 如果所有单词都不在其中,请包含文件.
  • 如果文件中包含 "不是任何"的话,请加入文件(即如果任何单词的肯定检查不正确)

所以你可以使用:

return myfiles.Where(file => filterbythesewords.All(item => !file.Contains(item));
Run Code Online (Sandbox Code Playgroud)

要么

return myfiles.Where(file => !filterbythesewords.Any(item => file.Contains(item));
Run Code Online (Sandbox Code Playgroud)

(这里不需要查询表达式 - 当你基本上只是做一个简单的过滤器时,查询表达式对可读性没有帮助.)