C++ 如何从 std::map 检索所有键(或值)并将它们放入向量中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/110157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:54:51  来源:igfitidea点击:

How to retrieve all keys (or values) from a std::map and put them into a vector?

c++dictionarystlstdmap

提问by Owen

This is one of the possible ways I come out:

这是我出来的可能方式之一:

struct RetrieveKey
{
    template <typename T>
    typename T::first_type operator()(T keyValuePair) const
    {
        return keyValuePair.first;
    }
};

map<int, int> m;
vector<int> keys;

// Retrieve all keys
transform(m.begin(), m.end(), back_inserter(keys), RetrieveKey());

// Dump all keys
copy(keys.begin(), keys.end(), ostream_iterator<int>(cout, "\n"));

Of course, we can also retrieve all values from the map by defining another functor RetrieveValues.

当然,我们也可以通过定义另一个函子RetrieveValues从地图中检索所有值。

Is there any other way to achieve this easily? (I'm always wondering why std::map does not include a member function for us to do so.)

有没有其他方法可以轻松实现这一目标?(我总是想知道为什么 std::map 不包含我们这样做的成员函数。)

采纳答案by Jere.Jones

While your solution should work, it can be difficult to read depending on the skill level of your fellow programmers. Additionally, it moves functionality away from the call site. Which can make maintenance a little more difficult.

虽然您的解决方案应该有效,但根据您的程序员同事的技能水平,它可能难以阅读。此外,它将功能从呼叫站点移开。这会使维护变得更加困难。

I'm not sure if your goal is to get the keys into a vector or print them to cout so I'm doing both. You may try something like this:

我不确定您的目标是将钥匙放入向量中还是将它们打印出来进行 cout,所以我两者都在做。你可以尝试这样的事情:

map<int, int> m;
vector<int> v;
for(map<int,int>::iterator it = m.begin(); it != m.end(); ++it) {
  v.push_back(it->first);
  cout << it->first << "\n";
}

Or even simpler, if you are using Boost:

或者更简单,如果您使用的是 Boost:

map<int,int> m;
pair<int,int> me; // what a map<int, int> is made of
vector<int> v;
BOOST_FOREACH(me, m) {
  v.push_back(me.first);
  cout << me.first << "\n";
}

Personally, I like the BOOST_FOREACH version because there is less typing and it is very explicit about what it is doing.

就个人而言,我喜欢 BOOST_FOREACH 版本,因为输入较少,而且它的作用非常明确。

回答by Juan

//c++0x too
std::map<int,int> mapints;
std::vector<int> vints;
vints.reserve(mapints.size());
for(auto const& imap: mapints)
    vints.push_back(imap.first);

回答by Alastair

There is a boost range adaptorfor this purpose:

有一个用于此目的的升压范围适配器

vector<int> keys;
// Retrieve all keys
boost::copy(m | boost::adaptors::map_keys, std::back_inserter(keys));

There is a similar map_values range adaptor for extracting the values.

有一个类似的 map_values 范围适配器用于提取值。

回答by DanDan

C++0x has given us a further, excellent solution:

C++0x 为我们提供了更进一步的优秀解决方案:

std::vector<int> keys;

std::transform(
    m_Inputs.begin(),
    m_Inputs.end(),
    std::back_inserter(keys),
    [](const std::map<int,int>::value_type &pair){return pair.first;});

回答by James Hirschorn

@DanDan's answer, using C++11 is:

@DanDan 的回答,使用 C++11 是:

using namespace std;
vector<int> keys;

transform(begin(map_in), end(map_in), back_inserter(keys), 
            [](decltype(map_in)::value_type const& pair) {
    return pair.first;
}); 

and using C++14 (as noted by @ivan.ukr) we can replace decltype(map_in)::value_typewith auto.

并使用 C++14(如@ivan.ukr 所述)我们可以decltype(map_in)::value_typeauto.

回答by Chris Jester-Young

The SGI STL has an extension called select1st. Too bad it's not in standard STL!

SGI STL 有一个扩展名为select1st. 太糟糕了,它不是标准的 STL!

回答by Brian R. Bondy

Your solution is fine but you can use an iterator to do it:

您的解决方案很好,但您可以使用迭代器来做到这一点:

std::map<int, int> m;
m.insert(std::pair<int, int>(3, 4));
m.insert(std::pair<int, int>(5, 6));
for(std::map<int, int>::const_iterator it = m.begin(); it != m.end(); it++)
{
    int key = it->first;
    int value = it->second;
    //Do something
}

回答by paxos1977

I think the BOOST_FOREACH presented above is nice and clean, however, there is another option using BOOST as well.

我认为上面介绍的 BOOST_FOREACH 很好而且很干净,但是,还有另一个使用 BOOST 的选项。

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

std::map<int, int> m;
std::vector<int> keys;

using namespace boost::lambda;

transform(      m.begin(), 
                m.end(), 
                back_inserter(keys), 
                bind( &std::map<int,int>::value_type::first, _1 ) 
          );

copy( keys.begin(), keys.end(), std::ostream_iterator<int>(std::cout, "\n") );

Personally, I don't think this approach is as clean as the BOOST_FOREACH approach in this case, but boost::lambda can be really clean in other cases.

就我个人而言,我认为这种方法在这种情况下不如 BOOST_FOREACH 方法干净,但 boost::lambda 在其他情况下确实很干净。

回答by Madiyar

Based on @rusty-parks solution, but in c++17:

基于@rusty-parks 解决方案,但在 c++17 中:

std::map<uint32_t, uint32_t> items;
std::vector<uint32_t> itemKeys;

for (const auto& [key, ignored]: items)
{
    itemKeys.emplace_back(key);
}

回答by Rusty Parks

Bit of a c++11 take:

c++11的一点点:

std::map<uint32_t, uint32_t> items;
std::vector<uint32_t> itemKeys;
for (auto & kvp : items)
{
    itemKeys.emplace_back(kvp.first);
    std::cout << kvp.first << std::endl;
}