[英]Copying C++ Map into key and value vectors
I have a map
and I want the first column ie (*it).first
to be pushed back into a vector then (*it)->second
to be pushed back into another vector 我有一个map
,我想要第一列, ie (*it).first
。首先被推回到一个向量然后(*it)->second
被推回到另一个向量
Is this the best way to do it? 这是最好的方法吗?
std::vector<std::string>test;
for ( it=mymap.begin() ; it != mymap.end(); it++ )
{
test.push_back((*it).first);
}
My other question is if i have a loop ie how would I insert all the integers i
into (*it).first
? 我的另一个问题是,如果我有一个循环,即我怎么会插入所有整数i
到(*it).first
?
for(int i = 0; i < 10; i++)
{
// 1 - 10 will go in (*it).first
}
I want to have some integers in (*it).first
and have associated values in (*it).second;
我想有一些整数(*it).first
,并有相关的价值观(*it).second;
Use std::transform
. 使用std::transform
。
First define two functions key
and value
which take the pair of strings and return the first or second value, respectively. 首先定义两个函数key
和value
,它们分别取出一对字符串并返回第一个或第二个值。
#include <map>
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
const std::string& key(const std::pair<std::string, std::string>& keyValue)
{
return keyValue.first;
}
const std::string& value(const std::pair<std::string, std::string>& keyValue)
{
return keyValue.second;
}
Then use std::transform
from <algorithm>
with the functions to transform the map into either a vector
of keys or a vector
of values. 然后使用std::transform
从<algorithm>
与所述功能到地图转变成任一vector
的键或一个vector
值。
int main()
{
using namespace std; // be explicit normally, trying to be brief here
map<string, string> contacts;
contacts["alice"] = "555-2701";
contacts["bob"] = "555-2702";
vector<string> keys(contacts.size());
vector<string> values(contacts.size());
transform(contacts.begin(), contacts.end(), keys.begin(), key);
transform(contacts.begin(), contacts.end(), values.begin(), value);
cout << "Keys:\n";
copy(keys.begin(), keys.end(), ostream_iterator<string>(cout, "\n"));
cout << "\n";
cout << "Values:\n";
copy(values.begin(), values.end(), ostream_iterator<string>(cout, "\n"));
return 0;
}
Output: 输出:
Keys:
alice
bob
Values:
555-2701
555-2702
Your first question, "how can I push the first column of my map into one vector and the 2nd column into another" is solved thus: 你的第一个问题,“如何将我的地图的第一列推入一个向量,将第二列推入另一个向量”得到解决:
std::map<std::string, std::string> mymap;
std::vector<std::string> keys;
std::vector<std::string> values;
for ( std::map<std::string,std::string>::iterator it=mymap.begin() ; it != mymap.end(); ++it )
{
keys.push_back(it->first);
values.push_back(it->second);
}
Your second question, "how would insert all the integers i
into (*it).first
?" 你的第二个问题,“怎么会插入所有整数i
到(*it).first
?” is solved thus: 这样解决了:
std::map<int, int> mymap2;
for(int i = 0; i < 10; i++)
{
// Insert default value into map
// This sets '(*it).first' to 'i' and
// '(*it).second' to a default value (in
// this case, 0).
mymap2[i];
}
or 要么
std::map<int, int> mymap3;
for(int i = 0; i < 10; i++)
{
// Insert specified value into map
// this sets '(*it).first' to 'i', and
// '(*it).second' to the value returned from the function.
maymap3[i] = ChooseSpecificValue(i);
}
Well, it can be done with a simple loop: 好吧,它可以通过一个简单的循环来完成:
for (auto const& p: mymap) {
vec1.push_back(p.first);
vec2.push_back(p.second);
}
Or using the std::transform
algorithm, though it's quite verbose here: 或者使用std::transform
算法,虽然它在这里非常详细:
std::transform(mymap.begin(), mymap.end(), std::back_inserter(vec1),
[](MyMap::const_reference p) { return p.first; });
Assuming you've declared your map as string key and value (ie map<string, string> mymap;
then it would be like below, also assuming you've declare 'it' variable as map<string, string>::iterator it
, etc: 假设你已经将你的地图声明为字符串键和值(即map<string, string> mymap;
那么它就像下面一样,也假设你已经将'it'变量声明为map<string, string>::iterator it
等等:
std::vector<std::string> test;
std::vector<std::string> second;
std::map<string, string>::iterator it;
for ( it=mymap.begin() ; it != mymap.end(); it++ )
{
test.push_back((*it).first);
second.push_back((*it).second);
}
Not sure about your next question. 不确定你的下一个问题。
and my other question is if i have a loop ie how would insert all the integers i into (*it).first? 而我的另一个问题是,如果我有一个循环,即如何将所有整数插入(*它).first?
In the case of a std::map
, you can't modify the iterator returned like that ... the key member (ie, the first) in the std::map
key/value pair data-structure is intentionally designated as a constant value, and is initialized to its constant value at the beginning of the key/value pair's lifetime in the std::map
data-structure. 在std::map
的情况下,你不能修改返回的迭代器...... std::map
键/值对数据结构中的键成员(即第一个)被有意指定为常量值,并在std::map
数据结构中的键/值对的生命周期的开始处初始化为其常量值。 If the keys weren't constant, you would end up creating havoc when you change the key, since the nodes in a std::map
are suppose to be sorted by the keys. 如果键不是常量,则在更改键时最终会造成严重破坏,因为std::map
中的节点假定按键排序。 The second member of the key/value pair data-structure is the member that can be changed. 键/值对数据结构的第二个成员是可以更改的成员。
So if you want to insert a set of key/value pairs in a map, you could simply do the following: 因此,如果要在地图中插入一组键/值对,则可以执行以下操作:
std::map<int, int> mymap;
int some_other_value = 100;
for (int i=0; i < 10; i++)
{
mymap[i] = some_other_value++;
}
The first part of your question: 问题的第一部分:
std::vector<std::string> test;
std::vector<std::string> test2; // assuming map is from string to string
for (it = mymap.begin(); it != mymap.end(); ++it)
{
test.push_back(it->first); // push first in one vector
test2.push_back(it->second); // push second in another vector
}
So, yes a simple for can do what you want. 所以,是的,一个简单的可以做你想要的。
The second part of your question: 问题的第二部分:
Since you are updating the key of the map, you would need to remove it from the map and insert the changed one. 由于您要更新地图的键,因此需要将其从地图中删除并插入更改的地图。 So: 所以:
std::string first, second;
first = it->first;
second = it->second;
mymap.erase(it); // be careful with invalidating iterator
// change first
mymap[first] = second;
To change first
by adding all integers i
to it, that would really depend on the type of first
. 要改变first
通过将所有整数i
给它,这真的取决于类型first
。 For example with a string, you may mean something like this: 例如,使用字符串,您可能意味着这样的事情:
ostringstream sout;
for (int i = 0; i < 10; ++i)
sout << (i?" ":"") << i;
first = sout.str();
Or if first is for example a set
, you may mean something like this: 或者,如果首先是例如一个set
,您可能意味着这样的事情:
for (int i = 0; i < 10; ++i)
first.insert(i);
it here will be an iterator which will point to one of the position in map and at max have one first and second value for one iterator . 它将是一个迭代器,它将指向map中的一个位置,并且最多只有一个迭代器的第一个和第二个值。 At max you can have multiple key or same key holding same/different values depending on key/value combination. 在最大值,您可以使用多个键或相同的键,保持相同/不同的值,具体取决于键/值组合。
As far as pushing the value in the vector for a key in map is concern you can do it in the same way you are pushing the key 至于在地图中按键的向量中推送值是值得关注的,你可以像按下键一样进行
std::vector<std::string>test;
std::vector<std::string>test2;
for ( it=mymap.begin() ; it != mymap.end(); it++ )
{
test.push_back((*it).first);
test2.push_back((*it).second);
}
Neways yours question is very unclear . 你的问题还不清楚。
Just in case you want to deal with different data types in your map I would template a generic copy function: 如果你想在地图中处理不同的数据类型,我会模拟一个通用的复制函数:
template <class A, class B>
void mycopy(std::map<A, B>&m, std::list<A>& keys, std::list<B>& values) {
typename std::map<A, B>::iterator it;
for (it = m.begin(); it != m.end(); ++it) {
keys.push_back( (*it).first );
values.push_back( (*it).second );
}
}
Mixing it up: 把它混合起来:
std::map<int, std::string> mymap;
std::list<int> keys;
std::list<std::string> values;
mymap[1] = "string1";
mymap[2] = "string2";
mycopy(mymap, keys, values);
std::map<std::string, int> mymap1;
std::list<std::string> keys1;
std::list<int> values1;
mymap1["string1"] = 1;
mymap1["string2"] = 2;
mycopy(mymap1, keys1, values1);
Edit: yes __copy isnt the best definition. 编辑:是__copy不是最好的定义。 Thanks 谢谢
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.