Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Friday, January 1, 2016

Case-Insensitive List Search

Case-Insensitive List Search


I have a list testList that contains a bunch of strings. I would like to add a new string into the testList only if it doesn't already exist in the list. Therefore, I need to do a case-insensitive search of the list and make it efficient. I can't use Contains because that doesn't take into account the casing. I also don't want to use ToUpper/ToLower for performance reasons. I came across this method, which works:

    if(testList.FindAll(x => x.IndexOf(keyword,                          StringComparison.OrdinalIgnoreCase) >= 0).Count > 0)         Console.WriteLine("Found in list");  

This works, but it also matches partial words. If the list contains "goat", I can't add "oat" because it claims that "oat" is already in the list. Is there a way to efficiently search lists in a case insensitive manner, where words have to match exactly? thanks

Answer by Adam Sills for Case-Insensitive List Search


Instead of String.IndexOf, use String.Equals to ensure you don't have partial matches. Also don't use FindAll as that goes through every element, use FindIndex (it stops on the first one it hits).

if(testList.FindIndex(x => x.Equals(keyword,        StringComparison.OrdinalIgnoreCase) ) != -1)       Console.WriteLine("Found in list");   

Alternately use some LINQ methods (which also stops on the first one it hits)

if( testList.Any( s => s.Equals(keyword, StringComparison.OrdinalIgnoreCase) ) )      Console.WriteLine("found in list");  

Answer by Ilya Kogan for Case-Insensitive List Search


You're checking if the result of IndexOf is larger or equal 0, meaning whether the match starts anywhere in the string. Try checking if it's equal to 0:

if (testList.FindAll(x => x.IndexOf(keyword,                      StringComparison.OrdinalIgnoreCase) >= 0).Count > 0)     Console.WriteLine("Found in list");  

Now "goat" and "oat" won't match, but "goat" and "goa" will. To avoid this, you can compare the lenghts of the two strings.

To avoid all this complication, you can use a dictionary instead of a list. They key would be the lowercase string, and the value would be the real string. This way, performance isn't hurt because you don't have to use ToLower for each comparison, but you can still use Contains.

Answer by Lance Larsen for Case-Insensitive List Search


Based on Adam Sills answer above - here's a nice clean extensions method for Contains... :)

///----------------------------------------------------------------------  ///   /// Determines whether the specified list contains the matching string value  ///   /// The list.  /// The value to match.  /// if set to true the case is ignored.  ///   ///   true if the specified list contais the matching string; otherwise, false.  ///   ///----------------------------------------------------------------------  public static bool Contains(this List list, string value, bool ignoreCase = false)  {      return ignoreCase ?          list.Any(s => s.Equals(value, StringComparison.OrdinalIgnoreCase)) :          list.Contains(value);  }  

Answer by Monkey in Pajamas for Case-Insensitive List Search


I had a similar problem, I needed the index of the item but it had to be case insensitive, i looked around the web for a few minutes and found nothing, so I just wrote a small method to get it done, here is what I did:

private static int getCaseInvariantIndex(List ItemsList, string searchItem)  {      List lowercaselist = new List();        foreach (string item in ItemsList)      {          lowercaselist.Add(item.ToLower());      }        return lowercaselist.IndexOf(searchItem.ToLower());  }  

Add this code to the same file, and call it like this:

int index = getCaseInvariantIndexFromList(ListOfItems, itemToFind);  

Hope this helps, good luck!

Answer by shaxby for Case-Insensitive List Search


I realise this is an old post, but just in case anyone else is looking, you can use Contains by providing the case insensitive string equality comparer like so:

if (testList.Contains(keyword, StringComparer.OrdinalIgnoreCase))  {      Console.WriteLine("Keyword Exists");  }  

This has been available since .net 2.0 according to msdn.

Answer by Pinaki Ghatak for Case-Insensitive List Search


Answer by Adam Sills about using FindIndex with Lambda expression totally worked for me. Thank you, Adam. :)


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.