2012-09-04 100 views
1

如何按值排序boost :: unordered_map并按顺序返回唯一键? 我有地图像boost :: unordered_map和我需要我需要onc的列表按int值排序的枚举在asc/desc中。如何按值排序** boost :: unordered_map **并按顺序返回唯一键?

+2

你需要对它进行排序吗?因为这或多或少是不可能的(理论上可能创建一个散列函数,这会导致一个排序的“无序:映射”)。否则,只需复制一个'map'(注意缺少'unordered_')(或者用适当的比较器将指针/迭代器放入'unordered_map'到'map'中),或者放入一个'vector'中并使用'sort'。 – Grizzly

+1

如果你需要对地图进行排序,你应该使用'map'而不是'unordered_map'。 –

回答

3

一种unordered_map是,顾名思义,固有地不排序或排序就地。您可以将值对插入set,该值按该值排序,并从那里获取密钥(使用Boost.Range使这个事情更容易)。我使用std::set<T*>来支付复制对象的费用。

#include <iostream> 
#include <set> 
#include <unordered_map> 
#include <boost/range/adaptor/map.hpp> 
#include <boost/range/adaptor/indirected.hpp> 
#include <boost/range/adaptor/transformed.hpp> 

struct compare_second{ 
    template<class Pair> 
    bool operator()(Pair* lhs, Pair* rhs) const{ 
    return lhs->second < rhs->second; 
    } 
}; 

template<class T> 
struct make_pointer{ 
    typedef T* result_type; 
    T* operator()(T& v) const{ return &v; } 
}; 

int main(){ 
    using namespace boost::adaptors; 
    std::unordered_map<int, int> m{{0,4},{1,3},{2,2},{3,1},{4,0}}; 
    typedef std::unordered_map<int,int>::value_type pair_type; 
    auto p = m | transformed(make_pointer<pair_type>()); 
    std::set<pair_type*, compare_second> value_ordered(p.begin(), p.end()); 
    for(auto x : value_ordered | indirected | map_keys) 
    std::cout << x << " "; 
} 

Live example.

+2

请注意,类似的事情可以用'std :: vector'和插入后排序来完成。 – Xeo

1

的最简单的方法是通过映射类型的值复制到载体中和对它们进行排序:

std::vector<value_type> values(std::begin(map), std::end(map)); 
boost::sort(boost::make_range(values), 
    [](const value_type &x, const value_type &y) { return x.second < y.second; }); 
std::vector<key_type> keys; 
boost::push_back(keys, boost::make_range(values) | boost::map_keys)); 
+0

我不知道boost库足够了,但我不确定提出的解决方案是否会生成按*映射值*排序的键的列表。解决这个问题的方法是相似的,但我担心它会花费更多的代码。再次,不熟悉库我可能不了解代码的作用。 –

+0

@DavidRodríguez-dribeas哦,我没有看到那个要求。定影。 – ecatmur