Joudicek Jouda
Joudicek Jouda

Reputation: 792

How to effectively select all values matching given pattern from a list of struct?

I've got a list of struct that holds a file extension name and a bool value (enabled/disabled).

I would like to effectively select all files from given folder, that match given extensions where the extension is set to enabled. I have found a similiar question on StackOverflow: GetFiles with multiple extensions But they are working with an array of strings, not structs.

Struct:

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

The only solution I was able to come with was:

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));
}

But that's a little dumb when there is an option of using Linq to have it much more effective.

Upvotes: 2

Views: 120

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726709

You are right, you can skip the preparatory step by using this LINQ query:

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

Being O(M*N), this implementation may be somewhat inefficient on very long lists of extensions applied to extremely large directories. In this case you would be better off constructing a Set<string> of enabled extensions, like this:

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));

Upvotes: 4

Related Questions