如何按值的升序对 std::map 进行排序?

How to sort a std::map by ascending order of value?

我正在尝试弄清楚如何按值的升序对 std::map 进行排序。

我的代码:

#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);
}

我想要的结果:

 pluto : 2
 mercury : 4
 mars : 6
 earth : 12
 venus : 12
 neptune : 49
 uranus : 51
 saturn : 120
 jupiter : 142

这可以用 std::map 来实现吗?

没有。无法按值对地图进行排序。

一个可能的解决方案:

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
}

一个std::map是按照它的排序的,而且不能改变(毕竟地图的点是快按键访问)。但是,您可以创建一个指向地图元素的指针容器,然后对其进行排序以便打印。您需要通过 const 引用传递您的地图,这样您的指针就不会失效:

#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';
                   });
}