C++ || How To Make Map & Unordered Map Keys Case Insensitive Using C++
The following is a module with functions which demonstrates how to make map and unordered_map keys case insensitive using C++.
1. Case Insensitive – Map
The example below demonstrates how to make a map with a string key case insensitive.
To do this, the comparison function needs to be overridden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// Case Insensitive - Map #include <string> #include <map> // Makes map keys case insensitive struct case_insensitive_map { struct comp { bool operator() (const std::string& lhs, const std::string& rhs) const { // On non Windows OS, use the function "strcasecmp" in #include <strings.h> return _stricmp(lhs.c_str(), rhs.c_str()) < 0; } }; }; // Declare map std::map<std::string, unsigned, case_insensitive_map::comp> map = { {"KENNetH", 2019}, {"Jennifer", 2010}, {"Lynn", 28}, {"SOLe", 31} }; // Display results std::cout << map["kenneth"] << ", " << map["JeNniFer"] << ", " << map["LYNN"] << ", " << map["sole"]; // expected output: /* 2019, 2010, 28, 31 */ |
2. Case Insensitive – Unordered Map
The example below demonstrates how to make an unordered map with a string key case insensitive.
To do this, the comparison and the hash function needs to be overridden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
// Case Insensitive - Unordered Map #include <string> #include <unordered_map> #include <utility> #include <cctype> // Makes unordered map keys case insensitive struct case_insensitive_unordered_map { struct comp { bool operator() (const std::string& lhs, const std::string& rhs) const { // On non Windows OS, use the function "strcasecmp" in #include <strings.h> return _stricmp(lhs.c_str(), rhs.c_str()) == 0; } }; struct hash { std::size_t operator() (std::string str) const { for (std::size_t index = 0; index < str.size(); ++index) { auto ch = static_cast<unsigned char>(str[index]); str[index] = static_cast<unsigned char>(std::tolower(ch)); } return std::hash<std::string>{}(str); } }; }; // Declare unordered map std::unordered_map<std::string, unsigned , case_insensitive_unordered_map::hash , case_insensitive_unordered_map::comp> unorderedMap = { {"KENNetH", 2019}, {"Jennifer", 2010}, {"Lynn", 28}, {"SOLe", 31} }; // Display results std::cout << unorderedMap["kenneth"] << ", " << unorderedMap["JeNniFer"] << ", " << unorderedMap["LYNN"] << ", " << unorderedMap["sole"]; // expected output: /* 2019, 2010, 28, 31 */ |
3. Full Examples
Below is a full example demonstrating the concepts on this page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
// ============================================================================ // Author: Kenneth Perkins // Date: Dec 8, 2020 // Taken From: http://programmingnotes.org/ // File: program.cpp // Description: The following demonstrates case insensitive maps. // ============================================================================ #include <iostream> #include <string> #include <exception> #include <map> #include <unordered_map> #include <utility> #include <cctype> void display(const std::string& message); // Makes map keys case insensitive struct case_insensitive_map { struct comp { bool operator() (const std::string& lhs, const std::string& rhs) const { // On non Windows OS, use the function "strcasecmp" in #include <strings.h> return _stricmp(lhs.c_str(), rhs.c_str()) < 0; } }; }; // Makes unordered map keys case insensitive struct case_insensitive_unordered_map { struct comp { bool operator() (const std::string& lhs, const std::string& rhs) const { // On non Windows OS, use the function "strcasecmp" in #include <strings.h> return _stricmp(lhs.c_str(), rhs.c_str()) == 0; } }; struct hash { std::size_t operator() (std::string str) const { for (std::size_t index = 0; index < str.size(); ++index) { auto ch = static_cast<unsigned char>(str[index]); str[index] = static_cast<unsigned char>(std::tolower(ch)); } return std::hash<std::string>{}(str); } }; }; int main() { try { // Declare map std::map<std::string, unsigned, case_insensitive_map::comp> map = { {"KENNetH", 2019}, {"Jennifer", 2010}, {"Lynn", 28}, {"SOLe", 31} }; // Display results std::cout << map["kenneth"] << ", " << map["JeNniFer"] << ", " << map["LYNN"] << ", " << map["sole"]; display(""); // Declare unordered map std::unordered_map<std::string, unsigned , case_insensitive_unordered_map::hash , case_insensitive_unordered_map::comp> unorderedMap = { {"KENNetH", 2019}, {"Jennifer", 2010}, {"Lynn", 28}, {"SOLe", 31} }; // Display results std::cout << unorderedMap["kenneth"] << ", " << unorderedMap["JeNniFer"] << ", " << unorderedMap["LYNN"] << ", " << unorderedMap["sole"]; } catch (std::exception& e) { display("\nAn error occurred: " + std::string(e.what())); } std::cin.get(); return 0; } void display(const std::string& message) { std::cout << message << std::endl; }// http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
Very cool stuff! 🙂 Can I just use the code, or?
Absolutely!