可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
How would I loop through a std::map
in C++?
My map is defined as:
std::map< std::string, std::map<std::string, std::string> >
For example, this holds data like this:
m[\"name1\"][\"value1\"] = \"data1\";
m[\"name1\"][\"value2\"] = \"data2\";
m[\"name2\"][\"value1\"] = \"data1\";
m[\"name2\"][\"value2\"] = \"data2\";
m[\"name3\"][\"value1\"] = \"data1\";
m[\"name3\"][\"value2\"] = \"data2\";
How can I loop through this map and access the various values?
回答1:
Old question but the remaining answers are outdated as of C++11 - you can use a ranged based for loop and simply do:
std::map<std::string, std::map<std::string, std::string>> mymap;
for(auto const &ent1 : mymap) {
// ent1.first is the first key
for(auto const &ent2 : ent1.second) {
// ent2.first is the second key
// ent2.second is the data
}
}
this should be much cleaner than the earlier versions, and avoids unnecessary copies.
Some favour replacing the comments with explicit definitions of reference variables (which get optimised away if unused):
for(auto const &ent1 : mymap) {
auto const &outer_key = ent1.first;
auto const &inner_map = ent1.second;
for(auto const &ent2 : inner_map) {
auto const &inner_key = ent2.first;
auto const &inner_value = ent2.second;
}
}
回答2:
You can use an iterator.
typedef std::map<std::string, std::map<std::string, std::string>>::iterator it_type;
for(it_type iterator = m.begin(); iterator != m.end(); iterator++) {
// iterator->first = key
// iterator->second = value
// Repeat if you also want to iterate through the second map.
}
回答3:
for(std::map<std::string, std::map<std::string, std::string> >::iterator outer_iter=map.begin(); outer_iter!=map.end(); ++outer_iter) {
for(std::map<std::string, std::string>::iterator inner_iter=outer_iter->second.begin(); inner_iter!=outer_iter->second.end(); ++inner_iter) {
std::cout << inner_iter->second << std::endl;
}
}
or nicer in C++0x:
for(auto outer_iter=map.begin(); outer_iter!=map.end(); ++outer_iter) {
for(auto inner_iter=outer_iter->second.begin(); inner_iter!=outer_iter->second.end(); ++inner_iter) {
std::cout << inner_iter->second << std::endl;
}
}
回答4:
Do something like this:
typedef std::map<std::string, std::string> InnerMap;
typedef std::map<std::string, InnerMap> OuterMap;
Outermap mm;
...//set the initial values
for (OuterMap::iterator i = mm.begin(); i != mm.end(); ++i) {
InnerMap &im = i->second;
for (InnerMap::iterator ii = im.begin(); ii != im.end(); ++ii) {
std::cout << \"map[\"
<< i->first
<< \"][\"
<< ii->first
<< \"] =\"
<< ii->second
<< \'\\n\';
}
}
回答5:
In C++17, you will be able to use the \"structured bindings\" feature, which lets you define multiple variables, with different names, using a single tuple/pair. Example:
for (const auto& [name, description] : planet_descriptions) {
std::cout << \"Planet \" << name << \":\\n\" << description << \"\\n\\n\";
}
The original proposal (by luminaries Bjarne Stroustrup, Herb Sutter and Gabriel Dos Reis) is fun to read (and the suggested syntax is more intuitive IMHO); there\'s also the proposed wording for the standard which is boring to read but is closer to what will actually go in.
回答6:
C++11:
std::map< std::string, std::map<std::string, std::string> > m;
m[\"name1\"][\"value1\"] = \"data1\";
m[\"name1\"][\"value2\"] = \"data2\";
m[\"name2\"][\"value1\"] = \"data1\";
m[\"name2\"][\"value2\"] = \"data2\";
m[\"name3\"][\"value1\"] = \"data1\";
m[\"name3\"][\"value2\"] = \"data2\";
for (auto i : m)
for (auto j : i.second)
cout << i.first.c_str() << \":\" << j.first.c_str() << \":\" << j.second.c_str() << endl;
output:
name1:value1:data1
name1:value2:data2
name2:value1:data1
name2:value2:data2
name3:value1:data1
name3:value2:data2
回答7:
use std::map< std::string, std::map<std::string, std::string> >::const_iterator
when map is const.