I have a:
map<string, map<int,int>>
Is there a way to print the contents of this map in alphabetical order, but case insensitive? For example, have it print in the following order:
A : 1:1, 2:2
a : 3:1
an : 2:1
And : 4:1
and : 3:1
Currently, I am printing using the following:
for (auto it = tokens.begin(); it != tokens.end(); ++it){
cout << it->first << " : ";
auto const &internal_map = it->second;
for (auto it2 = internal_map.begin(); it2 != internal_map.end(); ++it2){
if (it2 != internal_map.begin())
cout << " , ";
cout << it2->first << ":" << it2->second;
}
cout << endl;
}
This prints everything, however, it goes through all uppercase first, followed by all lowercase. For example:
A : 1:1, 2:2
And : 4:1
a : 3:1
an : 2:1
and : 3:1
Is there a way to print the contents of this map in alphabetical order, but case insensitive?
Yes.
You will have to create a custom compare functor that compares two strings in a case insensitive manner.
struct cicompare
{
bool operator()(std::string const& lhsIn, std::string const& rhsIn) const
{
char const* lhs = lhsIn.c_str();
char const* rhs = rhsIn.c_str();
for ( ; *lhs != '\0' && *rhs != '\0'; ++lhs, ++rhs )
{
if ( tolower(*lhs) != tolower(*rhs) )
{
return ( tolower(*lhs) < tolower(*rhs) );
}
else if ( *lhs != *rhs)
{
if ( *(lhs+1) == '\0' && *(rhs+1) == '\0' )
{
return (*lhs < *rhs);
}
}
}
return (tolower(*lhs) < tolower(*rhs));
}
};
Use the case insensitive compare functor to create the map.
map<string, map<int,int>, cicompare> mymap;
If you don't want to store your map ordered in a case insensitive manner, create a copy of the original map using cicompare
just before printing and print the new map.
map<string, map<int,int>, cicompare> mapForPrinting;
mapForPrinting.insert(originalMap.start(), originalMap.end());