Search code examples
c#csvdictionarystring-comparisonkeyvaluepair

Alter Methods So That Their Search Becomes Case In-Sensitive


I have two methods that I need to fix so that when a user searches for "Javascript", the methods will return values if they're spelled like "Javascript" or like "JavaScript" - capitalization won't matter. Importing data from the csv file (where the method performs its search) has already been done with LoadData(). The full code for the three files that I'm using (JobData.cs, Program.cs, job_data.csv) can be found here.

The first method that I need to fix is this one (found in JobData.cs, line 143):

 public static List<Dictionary<string, string>> FindByValue(string searchTerm)
    {
        LoadData();
        //set up a list of jobs that we're going to use to return from this method
        List<Dictionary<string, string>> jobs = new List<Dictionary<string, string>>();
        //row is a Dictionary<string, string>
        foreach (Dictionary<string, string> row in AllJobs)
        {
            //item is a KeyValuePair
            foreach (KeyValuePair<string, string> field in row)
            {
                string aValue = field.Value;
                if (aValue.Contains(searchTerm))
                {
                    jobs.Add(row);
                    break;
                }
            }
        }
        return jobs;
    }  

Maybe one way to do this is to break the searchTerms and values down so that they automatically become lowercase when the user searches. That way, even if the user types JAVAScript, it will automatically turn into javascript, and it will match the characters in the string field, which will also become lowercase. Of course we will still return the original string in field, whether it's "Javascript" or "JavaScript".

Another way to do this would be to automatically turn searchTerm case insensitive, so that it will match up with the field.Value regardless of capitalization.

Would doing that look like this?

  public static List<Dictionary<string, string>> FindByValue(string searchTerm)
    {
        LoadData();
        //set up a list of jobs that we're going to use to return from this method
        List<Dictionary<string, string>> jobs = new List<Dictionary<string, string>>();
        //row is a Dictionary<string, string>
        foreach (Dictionary<string, string> row in AllJobs)
        {
            //item is a KeyValuePair
            foreach (KeyValuePair<string, string> field in row)
            {
                string aValue = field.Value;
                //create new, case-insensitive searchTerm

                culture.CompareInfo.IndexOf(searchTerm, aValue, CompareOptions.IgnoreCase) >= 0

                if (aValue.Contains(searchTerm))
                {
                    jobs.Add(row);
                    break;
                }
            }
        }
        return jobs;
    }   

I'm trying to use this example of case insensitive string comparison. But using that line gives me error messages:

The name "culture" does not exist in the current context
The name "CompareOptions" does not exist in the current context

Any other ideas for how I can turn searchTerms case-insensitive when compared against field.aValue?


Solution

  • Your idea of using IndexOf instead of Contains is correct, you just have to use the right overload (the one that takes a StringComparison option). There are multiple options for a case-insensitive comparison. I'm using OrdinalIgnoreCase, but you can use the one that suits you best.

    Instead of this:

    aValue.Contains(searchTerm)
    

    Write this:

    aValue.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0