2013-05-08 22 views
2

我有一個保存文件擴展名和布爾值(啓用/禁用)的結構列表。如何有效地從結構列表中選擇所有匹配給定模式的值?

我想有效地選擇給定文件夾中的所有文件,匹配給定的擴展名,其中擴展名被設置爲啓用。 我在StackOverflow上發現了一個類似的問題: GetFiles with multiple extensions 但他們正在處理字符串數組,而不是結構體。

結構:

public struct MusicFileExtension 
{ 
    public string name { get; set; } 
    public bool enabled { get; set; } 
} 
public List<MusicFileExtension> Extensions; 

我能來,唯一的解決辦法是:

private IEnumerable<FileInfo> getFilesInFolderByExtensions(Options options, DirectoryInfo folderPath, SearchOption searchSubfolders) 
{    
     string [] ext = new string[options.Extensions.Count]; 
     int i =0; 
     foreach (Options.MusicFileExtension extension in options.Extensions) 
     { 
      if (extension.enabled) 
       ext[i] = extension.name; 
      i++; 
     } 
     IEnumerable<FileInfo> files = folderPath.EnumerateFiles(); 
     return files.Where(f => ext.Contains(f.Extension)); 
} 

但是,這是一個有點啞當有使用LINQ的一個選項,它更有效。

回答

4

你是對的,你可以使用這個LINQ查詢跳過準備步驟:

return files.Where(f => options.Extensions.Any(e => e.enabled && f.Extension == e.name)); 

作爲O(M*N),該實施可能對擴展很長的名單有點低效適用於非常大的目錄。在這種情況下,您最好是構建啓用的擴展程序的Set<string>,如下所示:

ISet<string> enabled = new HashSet<string>(
    options.Extensions.Where(e=>e.enabled).Select(e=>e.name) 
); 
IEnumerable<FileInfo> files = folderPath.EnumerateFiles(); 
return files.Where(f => enabled.Contains(f.Extension)); 
相關問題