Noah Roth
Noah Roth

Reputation: 276

Good way to search a directory for files that follow a specific naming convention?

My application allows clients to specify 80 images manually that will be utilized later on. However, I also offer functionality to automatically find and load these image files, as long as they follow a specific naming convention.

For example, the naming convention for these files is as follows:

*ClientName*_*ImageName*.png

Only PNG files are allowed, and ImageName is application-defined set of names. ClientName is ignored as it is defined client-side.

I am in the process of adding more images, and realize that my current way of handling this is not feasible.

Currently I get all files in a specified directory that have the PNG extension.

Then, my code is as follows (an example):

if (StringContains(currFile, "Tree"))
{
    // assign image "Tree"
}
else if (StringContains(currFile, "Bush"))
{
    // assign image "Bush"
}

...etc

My StringContains function simply does a String.IndexOf(currFile, StringComparison.CurrentCultureIgnoreCase) and returns true if the result is >= 0.

The first problem with this approach is the endless if/else if statements. It is not manageable.

The second issue is if I have an image that is called TreeMaple. I now need to change my if statement for finding the "Tree" image to this:

if (StringContains(currFile, "Tree") && !StringContains(currFile, "Maple"))

And you can imagine how crazy this gets when you add more image names like "TreeMapleFall", "TreeMapleWinter", "TreeMapleWinterSnow", etc., which is what I plan on doing.

How can I make this code more simple, maintainable and easier to read?

Upvotes: 0

Views: 55

Answers (1)

maraaaaaaaa
maraaaaaaaa

Reputation: 8163

Something along the lines of this may be easier:

string pattern = @"[^_]+_([^_]+)\.png";  // Regex pattern to capture *ImageName*
Regex regex = new Regex(pattern);
Match match = regex.Match(currFile);
if (match.Success)                       // If image abides by the format
{
    switch (match.Value) {               // Switch on the *ImageName*
        case "Tree":
            // Logic
            break;
        case "Bush":
            // Logic
            break;
        case "Maple":
            // Logic
            break;
    }
}

or using delegates:

Dictionary<string, Action> imageActions = new Dictionary<string, Action>();
if (match.Success && imageActions.ContainsKey(match.Value))   // If image abides by the format and a delegate exists for handling that image name
    imageActions[match.Value]();

// usage
imageActions.Add("Tree", () => { /* Logic */ });

Upvotes: 2

Related Questions