public Category(string path) { this.Path = path; // GetFileName returns just the name from a path, even for directories this.Name = System.IO.Path.GetFileName(path); string[] splitName = StringFuncs.SplitName(Name); ProductCode = splitName[0]; Metadata = splitName.ElementAtOrDefault(1); // sets to null if there is no other metadata if (Metadata is null) { MetaList = new string[] { "" }; // set to empty string to do intersection count } else { MetaList = StringFuncs.SplitMetadata(Metadata); } }
// Return the best category for a given image public static Category FindCategory(string imageName, Dictionary <string, List <Category> > categories) { var comparer = StringComparer.OrdinalIgnoreCase; // used to ignore case in comparisons string[] splitName = StringFuncs.SplitName(imageName); string productName = splitName[0]; string metadata = splitName.ElementAtOrDefault(1); // returns null if there is no metadata // Return null if there is no matching category if (!categories.ContainsKey(productName)) { Console.WriteLine("No category for {0}", imageName); return(null); } // Narrow down the categories to just ones with a matching product name var matchingCategories = categories[productName]; // If the image only has a name, return category with no other metadata if (metadata is null) { Category baseCategory = matchingCategories.First(cat => cat.Metadata is null); return(baseCategory); } List <string> metaList = StringFuncs.SplitMetadata(metadata).ToList(); // Sort by number of matching metadata items between categories and images. // This is done through ordering the count of the intersection between the two. // Doing it this way handles arbitrary ordering and number of metadata tags. IEnumerable <Category> match = matchingCategories .OrderByDescending(cat => metaList.Intersect(cat.MetaList, comparer).Count()); // Remove all cases where the category has more metadata than the image. // Keep categories without metadata (metaList[0] = ""). match = match.Where(cat => cat.MetaList[0] == "" || !cat.MetaList.Except(metaList, comparer).Any()); // Return the best match return(match.Any() ? match.First() : null); }