How can I implement STL map sorting by value?
For example, I have a map m:
map m;
m[1] = 10;
m[2] = 5;
m[4] = 6;
m[6] =
Based on @swegi's idea, I implemented a solution in c++11 using a multimap:
map m = {{1, 10}, {2, 5}, {4, 6}, {6, 1}};
multimap mm;
for(auto const &kv : m)
mm.insert(make_pair(kv.second, kv.first)); // Flip the pairs.
for(auto const &kv : mm)
cout << "m[" << kv.second << "] = " << kv.first << endl; // Flip the pairs again.
Code on Ideone
I also implemented a C++11 solution based on @Chris' idea using a vector of pairs. For correct sorting, I provide a lambda expression as comparison functor:
map m = {{1, 10}, {2, 5}, {4, 6}, {6, 1}};
using mypair = pair;
vector v(begin(m), end(m));
sort(begin(v), end(v), [](const mypair& a, const mypair& b) { return a.second < b.second; });
for(auto const &p : v)
cout << "m[" << p.first << "] = " << p.second << endl;
Code on Ideone
The first solution is more compact, but both solutions should have roughly the same performance. Inserting into a multimap is of O(log n), but this has to be done for n entries, resulting in O(n log n). Sorting the vector in the second solution also results in O(n log n).
I also gave a try to @Chris' idea on using a set of pairs. However, it won't work if the values aren't all distinct. Using a functor that compares only the pair's second element doesn't help. If you first insert make_pair(1, 1) into the set and then try to insert make_pair(2, 1), then the second pair won't be inserted, because both pairs are seen as identical by that set. You can see that effect here on Ideone.