Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create my own comparator for a map?

Tags:

c++

stl

stdmap

typedef map<string, string> myMap;

When inserting a new pair to myMap, it will use the key string to compare by its own string comparator. Is it possible to override that comparator? For example, I'd like to compare the key string by its length, not by the alphabet. Or is there any other way to sort the map?

like image 982
Xitrum Avatar asked Apr 20 '11 16:04

Xitrum


People also ask

How to make comparator in map?

Specify the type of the pointer to your comparison function as the 3rd type into the map, and provide the function pointer to the map constructor: map<keyType, valueType, typeOfPointerToFunction> mapName(pointerToComparisonFunction);

Can we use comparator with map in C++?

Method 2 – using the set of pairs The idea is to insert all the (key-value) pairs from the map into a set of pairs that can be constructed using a comparator function that orders the pairs according to the second value. Multimap is similar to a map with an addition that multiple elements can have the same keys.

How do you write a comparator function in C++?

Comparator Classes are used to compare the objects of user-defined classes. In order to develop a generic function use template, and in order to make the function more generic use containers, so that comparisons between data can be made.

How can I compare two maps in C++?

C++ Map Library - operator== Functionb The C++ function std::map::operator== tests whether two maps are equal or not.


2 Answers

std::map takes up to four template type arguments, the third one being a comparator. E.g.:

struct cmpByStringLength {
    bool operator()(const std::string& a, const std::string& b) const {
        return a.length() < b.length();
    }
};

// ...
std::map<std::string, std::string, cmpByStringLength> myMap;

Alternatively you could also pass a comparator to maps constructor.

Note however that when comparing by length you can only have one string of each length in the map as a key.

like image 138
Georg Fritzsche Avatar answered Oct 18 '22 02:10

Georg Fritzsche


Since C++11, you can also use a lambda expression instead of defining a comparator struct:

auto comp = [](const string& a, const string& b) { return a.length() < b.length(); };
map<string, string, decltype(comp)> my_map(comp);

my_map["1"]      = "a";
my_map["three"]  = "b";
my_map["two"]    = "c";
my_map["fouuur"] = "d";

for(auto const &kv : my_map)
    cout << kv.first << endl;

Output:

1
two
three
fouuur

I'd like to repeat the final note of Georg's answer: When comparing by length you can only have one string of each length in the map as a key.

Code on Ideone

like image 34
honk Avatar answered Oct 18 '22 03:10

honk