Reputation: 3044
I'm trying to figure out how to sort std::map
by ascending order of value.
My Code :
#include <iostream>
#include <map>
#include <string>
#include <iterator>
void printMapByOrder(std::map<std::string, int> mapOfPlanets)
{
//what should be here?
}
int main() {
std::map<std::string, int> mapOfPlanets;
mapOfPlanets["earth"] = 12;
mapOfPlanets["jupiter"] = 142;
mapOfPlanets["mars"] = 6;
mapOfPlanets["mercury"] = 4;
mapOfPlanets["neptune"] = 49;
mapOfPlanets["pluto"] = 2;
mapOfPlanets["saturn"] = 120;
mapOfPlanets["uranus"] = 51;
mapOfPlanets["venus"] = 12;
printMapByOrder(mapOfPlanets);
}
The Result I want :
pluto : 2
mercury : 4
mars : 6
earth : 12
venus : 12
neptune : 49
uranus : 51
saturn : 120
jupiter : 142
Is this possible to do this with std::map
?
Upvotes: 0
Views: 2327
Reputation: 30822
A std::map
is ordered by its keys, and that can't be changed (after all, the point of a map is fast access by key). You could, however, create a container of pointers to your map elements, and sort that for printing. You'll want to pass your map by const reference, so that your pointers won't be invalidated:
#include <algorithm>
#include <vector>
void printMapByOrder(const std::map<std::string, int>& mapOfPlanets)
{
using element = typename std::map<std::string, int>::value_type;
std::vector<const element*> sorted;
sorted.reserve(mapOfPlanets.size());
for (auto& planet: mapOfPlanets)
sorted.push_back(&planet);
# sort by value
std::sort(sorted.begin(), sorted.end(),
[](auto *a, auto *b) {
return std::tie(a->second, a->first)
< std::tie(b->second, b->first);
});
# print results
std::transform(sorted.begin(), sorted.end(),
std::ostream_iterator<std::string>(std::cout),
[](const auto *p) {
return p->first + ": "
+ std::to_string(p->second) + '\n';
});
}
Upvotes: 3
Reputation: 10962
No. Its not possible to sort a map by its values.
One possible solution:
void printMapByOrder(std::map<std::string, int> mapOfPlanets)
{
std::vector < std::pair<std::string, int> > planets(mapOfPlanets.begin(), mapOfPlanets.end());
std::sort(planets.begin(), planets.end(), [](auto lhs, auto rhs) {return lhs.second < rhs.second; });
//print planets
}
Upvotes: 4