Date: 2007nov27
Language: C/C++
Q. How can I make a STL map with a case insensitive string for key?
A. There are several ways.
1. Convert the key to lowercase before using.
2. You can make your own std::string-like class where the compares
are not case sensitive.
3. You can use traits to make std::string case insensitive.
4. You can supply a 3rd parameter for comparing to the <map> template
as we show here...
from
http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=2902
// disable warnings about long names
#ifdef WIN32
#pragma warning( disable : 4786)
#endif
#include <string>
#include <map>
#include <iostream>
using namespace std;
// case-independent (ci) string less_than
// returns true if s1 < s2
struct ci_less : binary_function<string, string, bool>
{
// case-independent (ci) compare_less binary function
struct nocase_compare : public 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 string & s1, const string & s2) const
{
return lexicographical_compare
(s1.begin (), s1.end (), // source range
s2.begin (), s2.end (), // dest range
nocase_compare ()); // comparison
}
}; // end of ci_less
// OR a simpler (and probably faster) version (by dave):
struct ci_less
{
bool operator() (const string & s1, const string & s2) const
{
return stricmp(s1.c_str(), s2.c_str()) < 0;
}
};
typedef map<string, int, ci_less> age_map;
int main()
{
// make a map of people
age_map people;
// add items to list
people ["Nick"] = 28;
people ["John"] = 14;
people ["Mary"] = 88;
// find someone by key
cout << "Finding person 'nick' ..." << endl;
age_map::const_iterator i = people.find ("nick");
if (i == people.end ())
cout << "Not found." << endl;
else
cout << "Found age = " << i->second << endl;
return 0;
} // end of main
Output
Finding person 'nick' ...
Found age = 28