当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何从std::map中检索所有键(或值)并将它们放入向量中?》经验,为你挑选了12个好方法。

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

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

map m;
vector keys;

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

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

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

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



1> Jere.Jones..:

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

我不确定你的目标是将密钥放入矢量中还是将它们打印到cout所以我正在做两件事.你可以尝试这样的事情:

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

或者甚至更简单,如果你使用Boost:

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

就个人而言,我喜欢BOOST_FOREACH版本,因为键入的内容较少,而且它的内容非常明确.


好奇,预先设定矢量以防止调整大小分配是不是有意义?
@Jere - 你真的和`BOOST_FOREACH`合作过吗?你在这里提出的代码是完全错误的
@Jamie - 这是另一种方式,但是如果类型包含逗号,则boost文档显示在BOOST_FOREACH之前指定变量及其类型.他们还显示了typedefing它.所以,我很困惑,我的代码出了什么问题?
不要忘记执行`v.reserve(m.size())`以避免在传输过程中调整矢量大小.

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


@BenHymers但它现在对任何读这个问题的人都有用,这就是SO的全部意义 - 不仅帮助提问者,还帮助其他所有人.
for(auto&imap)更精确,因为没有复制操作.
尼斯.忘记`it = ... begin(); 它!= ...结束.最好的当然是std :: map有一个方法keys()返回该向量...
@BenHymers:在我看来,这个答案是在12月12日22:33回答的,这是几个月后_C++ 11变成了C++.
@StudentT,更好的是,`for(auto const&imap:mapints)`.
我更喜欢`for(auto && imap:mapints)`.见http://edmundv.home.xs4all.nl/blog/2014/01/28/use-auto-and-and-for-range-based-for-loops/
此外,我们中的一些人必须在没有C++ 11支持的环境中工作-_-

3> Alastair..:

为此目的有一个增压范围适配器:

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

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


这真遗憾.Boost 1.42于2010年2月发布,距离Squeeze超过2.5年.

4> DanDan..:

C++ 0x为我们提供了更好的解决方案:

std::vector keys;

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


在我看来,没有什么优秀的.std :: vector 键; keys.reserve(m_Inputs.size()); for(auto keyValue:m_Inputs){keys.push_back(keyValue.first); 比神秘的变换要好得多.即使在性能方面.这个更好.
只想添加 - 可以使用[](const auto&pair)
如果您想要相同的性能,也可以在此处保留按键的大小.如果要避免for循环,请使用转换.
lambda中的@ ivan.ukr自动参数是c ++ 14

5> James Hirsch..:

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

using namespace std;
vector keys;

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

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


您可以添加`keys.reserve(map_in.size());`以提高效率.

6> Chris Jester..:

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



7> paxos1977..:

我认为上面提到的BOOST_FOREACH很好很干净,但是,还有另一个使用BOOST的选项.

#include 
#include 

std::map m;
std::vector keys;

using namespace boost::lambda;

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

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

就个人而言,我不认为这种方法在这种情况下与BOOST_FOREACH方法一样干净,但在其他情况下,boost :: lambda可能非常干净.



8> Brian R. Bon..:

您的解决方案很好,但您可以使用迭代器来执行此操作:

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



9> Marcelo Cant..:

此外,如果您有Boost,请使用transform_iterator以避免生成密钥的临时副本.



10> 小智..:

C ++ 11的特点:

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



11> amit..:

您可以使用通用的boost :: transform_iterator。transform_iterator允许您转换迭代的值,例如在我们的情况下,当您只想处理键而不是值时。参见http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/transform_iterator.html#example



12> Clemens Siel..:

这是一个使用C ++ 11魔术的不错的函数模板,可同时用于std :: map和std :: unordered_map:

template