获取map或set中的key到vector中的方法

简介

有时需要对map中的key进行一些单独的处理,这时将它们拷贝到一个vector中再处理会方便些。

以下方法对unordered_map同样适用。以key为string类型为例。

先介绍几种获取map中key的方法,对于获取set中key的方法,与map类似。文末简要介绍。

遍历取值

这是普通朴素的方法,直接上代码:

// 省略头文件和using声明
template<typename T>
void MapKeysToVector(const T& in, vector<string>& out)
{
	out.reserve(in.size()); // 提前为vector分配空间,避免因为中途空间重新分配损失效率
	for (const auto& data : in) {
		out.emplace_back(data.first); // c11的emplace_back()比push_back()高效,置入比插入省略了临时中间对象的构造过程
	}
}
transform + boost

使用标准算法同样达到目的:

#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <boost/bind.hpp>

int main()
{
   typedef std::map<std::string, int> MapT;
   typedef std::vector<std::string> VecT;
   MapT map;
   VecT vec;

   map["one"] = 1;
   map["two"] = 2;
   map["three"] = 3;
   map["four"] = 4;
   map["five"] = 5;

   std::transform( map.begin(), map.end(),
                   std::back_inserter(vec),
                   boost::bind(&MapT::value_type::first, _1) ); // use boost::bind to access the first or second value of the pair
}
transform + lambda

上述使用boost::bind的方法可以使用lambda替换:

#include <algorithm> // std::transform
#include <iterator>  // std::back_inserter

std::transform( 
    map.begin(), 
    map.end(),
    std::back_inserter(vec), // 需要使用back_inserter,它会自动为vector分配空间
    [](auto &kv){ return kv.first;} // 返回输入迭代器的key,需要c++14
);
std::for_each

使用for_each迭代结合lambda:

{
   std::map<std::string,int> m;
   std::vector<int> v;
   
   v.reserve(m.size()); // 提前分配好空间
   std::for_each(m.begin(),m.end(),
                 [&v](const std::map<std::string, int>::value_type& p) 
                 { v.push_back(p.first); });
}
boost

使用boost库提供的函数boost range adaptor,如下:

#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>

map<string, int> m;
// ...
// insert values to m
vector<string> keys;
boost::copy(m | boost::adaptors::map_keys, std::back_inserter(keys));
小结

以上方法能够获取map的keys到vector,稍做修改,就可以获取到map的value到vector。

具体使用时,可根据项目组的使用习惯选择。如果对boost不熟悉,不建议选择boost方法,这会增加学习维护成本。

如果对stl算法库也不熟悉,建议使用最朴素的解法。这样你的同事也可以轻易理解并维护代码。

获取set的key到vector

对于set比较简单,因为它不是std::pair类型的数据。

直接上方法:

set<string> input; // insert values to input

// 遍历取值方式略
// 直接std::copy,需要使用std::back_inserter
std::copy(input.begin(), input.end(), std::back_inserter(output));

// 先分配内存,再直接copy
std::vector<string> output(input.size());
std::copy(input.begin(), input.end(), output.begin());

// range constructor
std::vector<string> output(input.begin(), input.end()); 

// vector.assign()
vector<string> v;
v.assign(input.begin(), input.end());
总结

  • 根据代码便于维护原则,选择项目组最熟悉的方法即可
  • 根据代码简洁原则,选择使用stl算法,如transform/copy
  • 如果经常使用boost库,可以选择boost
  • 对于set比较简单,使用直接构造或者assign更简洁
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值