LINQ where子句与Func<>结合使用和Foreach

时间:2012-12-15 18:10:14

标签: c#

我想做什么:

我有一个扩展名列表(.mpg,.avi,.jpg)...和一个文件名列表(stuff.jpg,dogs.txt,movie.avi)。

我想将文件名列表与扩展名列表进行比较,并且只保留扩展名匹配的文件。在上面的示例中,将是stuff.jpg和movie.avi,dogs.txt应该被忽略。

我是怎么做的:

我有一个字符串列表(文件扩展名,如.mp3,mp4,.avi ...):

        List<String>  extensions = new List<string>();
        extensions.Add(".mp4");
        extensions.Add(".mp3");
        extensions.Add(".avi");
        extensions.Add(".mkv");
        extensions.Add(".mpeg");
        extensions.Add(".mpg");

我还有一个包含多个文件的IEnumerable。

我想要做的是检查IEnumerable中的每个文件,看它是否有一个扩展名与我上面列表中的一个扩展名匹配(所以.mpg,.mp3 ...)。

现在我这样做:

    var files = dir.EnumerateFiles();
    var newlist = files.Where(doesItMatch).Select(x => x).ToList();

    private Func<FileInfo, bool> doesItMatch = x =>
            {
                return x.Extension == ".mp3";
            };

这有效,但显然它只会检查它是否匹配“.mp3”。问题是我不想开始做像

这样的事情
where x == ".mp4" || x == ".avi" || x == ".mpg" ....

我基本上想要遍历扩展列表中的每个元素,并将其与IEnumerable中文件的当前扩展名进行匹配。

我尝试过像这样的foreach:

 var newlist = files.Where(file => extensions.ForEach(ext => file.Extension == ext) ).Select(x => x).ToList();

但是这给了我file.Extension == ext部分的错误,说明只有“赋值,调用......可以用作语句”。

所以我的问题是,我可以使用上面描述的Func<>与扩展列表中的某种foreach相结合吗?或者我应该寻找另一种方法吗?

2 个答案:

答案 0 :(得分:4)

var files = Directory.EnumerateFiles(path)
                     .Where(f => extensions.Contains(new FileInfo(f).Extension))
                     .ToList();

并使用您的doesItMatch

var extensions = new HashSet<string>(new[] { ".mp4", ".mp3", ".avi",".mkv",".mpeg",".mpg" });

Func<string, bool> doesItMatch = x => extensions.Contains(new FileInfo(x).Extension);

var files = Directory.EnumerateFiles(path)
                     .Where(f => doesItMatch(f))
                     .ToList();

答案 1 :(得分:2)

避免必须创建函数的另一种方法&lt;&gt;搜索只是使用ANY linq方法:

List<string> extenstions = new List<string>
{
   ".txt",
   ".pdf"
};

DirectoryInfo dir = new DirectoryInfo(@"C:\Users\Administrator\Desktop");

IEnumerable<FileInfo> foundFiles = dir.EnumerateFiles().Where(f => ext.Any(e => f.Extension == e));