2012-12-15 25 views
2

我究竟想做组合:LINQ where子句中使用Func键<>和foreach

我有扩展名的列表(.MPG,.AVI,.JPG)...和文件名列表(东东.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结合吗?或者我应该寻找另一种方式来做到这一点?

回答

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

我认为新的FileInfo(f)应该是新的FileInfo(f.FullName),但除此之外它的作品!非常感谢。另外,对于这种特殊情况使用Func <>是不好的做法吗?还是可以接受? – Thousand

2

这避免了必须建立一个FUNC <>搜索将只使用任何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));