查找std :: unordered_map中与相同值对应的所有键

时间:2015-06-17 12:45:16

标签: c++ c++11 stl c++14

我的unordered_map看起来像这样:

std::unordered_map<int, std::string> theMap2 = {{1,"a"}, {2,"b"}, {3,"c"}, {4,"a"}};

我想找到所有具有相同值的键让我们说“a”。除了显而易见的方式之外的任何建议:

std::vector<int> arrKeys;
std::string value = "a";
for (const auto& element : theMap)
   if (element.second == value)
        arrKeys.push_back(element.first); 

2 个答案:

答案 0 :(得分:9)

我认为“显而易见”的方式非常好:它简单,简洁,易于阅读。

另一种选择是使用stl算法。您需要的是transform_if算法,因此您可以说:

std::transform_if(std::begin(theMap), std::end(theMap),  std::back_inserter(arrKeys), check_value, get_value);

但在stl中没有这样的。我可以建议的是:

std::vector<int> arrKeys;
std::string value = "a";

auto check_value = [&](std::pair<const int, std::string> const& p)->bool
{
    return (p.second == value);
};

auto end = std::end(theMap);
auto it = find_if(std::begin(theMap), end, check_value);
while (it != end)
{
    arrKeys.push_back(it->first);
    it = find_if(std::next(it), end, check_value);
}

答案 1 :(得分:2)

更多的是出于兴趣而不是其他任何东西,我写了一个可用于copy_if的基本包装器。它类似于std::back_inserter,但它不是仅插入给定的对象,而是插入std::get<N>(obj)。这使其可用于std::arraystd::tuplestd::pair

要在此示例中插入pair.first,我们使用back_n_inserter<0>

template< std::size_t N, class Container >
class back_n_insert_iterator : public std::iterator< std::output_iterator_tag,
                                                         void, void, void, void >
{
public:
    back_n_insert_iterator (Container& c) : c{c} {};

    //could protect this by checking that the get call is_convertible to the value_type
    template <typename T>
    decltype(auto) operator= (T&& collec) 
    {
        c.push_back(std::get<N>(std::forward<T>(collec)));
        return *this;
    }

    decltype(auto) operator* () { return *this; }
    decltype(auto) operator++ () { return *this; }
    decltype(auto) operator++ (int) { return *this; }
private:
    Container& c;
};

template< std::size_t N, class Container >
back_n_insert_iterator<N,Container> back_n_inserter( Container& c )
{
    return {c};
}

现在我们可以在copy_if电话中使用我们的适配器:

std::copy_if(theMap.begin(), theMap.end(), 
             back_n_inserter<0>(arrKeys),
             [&value](const auto& el){return el.second == value;});

感谢@dyp提供所有建议。