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

news/2024/9/28 11:12:06 标签: map, set, vect

简介


有时需要对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算法库也不熟悉,建议使用最朴素的解法。这样你的同事也可以轻易理解并维护代码。

setkeyvector_116">获取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更简洁

http://www.niftyadmin.cn/n/1630015.html

相关文章

Anaconda入门:解决CondaHTTPError: HTTP 000 CONNECTION FAILED for url

简介 Anaconda 是一个用于科学计算的 Python 发行版&#xff0c;支持 Linux, Mac, Windows, 包含了众多流行的科学计算、数据分析的 Python 包。 类似于Ubuntu是Linux的发行版&#xff0c;你基本不会直接去使用Linux&#xff0c;而是选择一个发行版&#xff0c;如Ubuntu/CentO…

php+sqlite cms

1 phpSQLiteCMS 最新版本 phpSQLiteCMS 2.0.4 http://phpsqlitecms.net/ 2 taoCMS 最新版本 【2.5Beta5下载地址】 需要php 开启php_sqlite.dll 官方下载(体积180K,最后一次更新2012年11月17日)如果您是在11月17日前下载&#xff0c;请立即下载更新补丁 github地址&#xff1…

程序员如何不加班?—— 技术提升篇

背景 在如今福报和996盛行的互联网世界里&#xff0c;仿佛不加班的程序员已经不是好程序员了。 在以前&#xff0c;加班从来都是不得不的临时应对策略。比如明天就要验收了&#xff0c;今天得把所有项目收尾做完。下周就要出差了&#xff0c;你加会班把手头的任务做一了结。 …

win10便捷安装TensorFlow2——使用Anaconda

简介 机器学习是指帮助软件在没有明确的程序或规则的情况下执行任务。 对于传统计算机编程&#xff0c;程序员会指定计算机应该使用的规则。但是&#xff0c;机器学习需要另一种思维方式。 现实中的机器学习对数据分析的注重程度远高于编码。程序员提供一组样本&#xff0c;然…

轻量级消息队列

2019独角兽企业重金招聘Python工程师标准>>> 1. UCMQ简介 UCMQ是一款支持简单HTTP协议的轻量级消息队列服务&#xff0c;基本特性如下&#xff1a; l 支持HTTP协议的GET/POST方法&#xff0c;支持长连接&#xff08;keep-alive&#xff09;&#xff1b; l 请求…

量化基金投资简介

投资 广义上&#xff0c;把资金用于购买资产&#xff0c;并期待资产增值带来更多的资金收益&#xff0c;就是投资。 投资中的两个关键因素&#xff1a;收益和风险。 所有人都希望投资的收益越高越好&#xff0c;风险越低越好。 但高收效和低风险就像是跷跷板的两端&#xff…

程序员如何不加班?—— 时间管理篇

“时间管理” “时间管理”这个词现在是大红大紫了。 围绕这个话题&#xff0c;谁都可以说上一通。 然而说完仍然是云里雾里… 说白了&#xff0c;这里用这个名字就是为了蹭热点&#xff08;不要脸&#xff09;&#xff0c;哈哈。 我以为&#xff0c;时间是不可管理的。每个…

smb与samba

为了使Windows 主机间的资源能够共享&#xff0c;微软于1980年开发了SMB&#xff08;Server Message Block&#xff09;通信协议&#xff0c;并通过SMB通信协议&#xff0c;使网络上各台主机之间能够共享文件、打印机等资源。目前类似这种资源共享的通信协议还有NFS、Appletalk…