How can I create my own comparator for a map?

2019-01-04 23:28发布

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?

标签: c++ stl stdmap
3条回答
Ridiculous、
2楼-- · 2019-01-04 23:57

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

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-01-05 00:02

Yes, the 3rd template parameter on map specifies the comparator, which is a binary predicate. Example:

struct ByLength : public std::binary_function<string, string, bool>
{
    bool operator()(const string& lhs, const string& rhs) const
    {
        return lhs.length() < rhs.length();
    }
};

int main()
{
    typedef map<string, string, ByLength> lenmap;
    lenmap mymap;

    mymap["one"] = "one";
    mymap["a"] = "a";
    mymap["fewbahr"] = "foobar";

    for( lenmap::const_iterator it = mymap.begin(), end = mymap.end(); it != end; ++it )
        cout << it->first << "\n";
}
查看更多
Bombasti
4楼-- · 2019-01-05 00:12

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.

查看更多
登录 后发表回答