Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make the map::find operation case insensitive?

Does the map::find method support case insensitive search? I have a map as follows:

map<string, vector<string> > directory; 

and want the below search to ignore case:

directory.find(search_string); 
like image 410
TL36 Avatar asked Nov 26 '09 06:11

TL36


People also ask

How do you make a case insensitive in C++?

Case-insensitive string comparison in using C++11 lambda function and equals() Logic is same as above, use std::equals() but instead of another global function use lambda function and make solution in single line i.e.

How do you ignore a case on a map?

Therefore, if we provide a case-insensitive String Comparator, we'll get a case-insensitive TreeMap. which we can supply in the constructor: Map<String, Integer> treeMap = new TreeMap<>(String. CASE_INSENSITIVE_ORDER); treeMap.

Is map key case sensitive in C++?

If you use the standard std::map associative container with std::string or std::wstring as key types, you get a case sensitive comparison by default.


1 Answers

It does not by default. You will have to provide a custom comparator as a third argument. Following snippet will help you...

  /************************************************************************/   /* Comparator for case-insensitive comparison in STL assos. containers  */   /************************************************************************/   struct ci_less : std::binary_function<std::string, std::string, bool>   {     // case-independent (ci) compare_less binary function     struct nocase_compare : public std::binary_function<unsigned char,unsigned char,bool>      {       bool operator() (const unsigned char& c1, const unsigned char& c2) const {           return tolower (c1) < tolower (c2);        }     };     bool operator() (const std::string & s1, const std::string & s2) const {       return std::lexicographical_compare          (s1.begin (), s1.end (),   // source range         s2.begin (), s2.end (),   // dest range         nocase_compare ());  // comparison     }   }; 

Use it like std::map< std::string, std::vector<std::string>, ci_less > myMap;

NOTE: std::lexicographical_compare has some nitty-gritty details. String comparison isn't always straightforward if you consider locales. See this thread on c.l.c++ if interested.

UPDATE: With C++11 std::binary_function is deprecated and is unnecessary as the types are deduced automatically.

  struct ci_less   {     // case-independent (ci) compare_less binary function     struct nocase_compare     {       bool operator() (const unsigned char& c1, const unsigned char& c2) const {           return tolower (c1) < tolower (c2);        }     };     bool operator() (const std::string & s1, const std::string & s2) const {       return std::lexicographical_compare          (s1.begin (), s1.end (),   // source range         s2.begin (), s2.end (),   // dest range         nocase_compare ());  // comparison     }   }; 
like image 87
Abhay Avatar answered Sep 21 '22 02:09

Abhay