How can I loop through a C++ map of maps?

ID : 10421

viewed : 37

Tags : c++loopsdictionaryiterationidiomsc++

Top 5 Answer for How can I loop through a C++ map of maps?

vote vote

93

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;   } } 
vote vote

89

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. } 
vote vote

79

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;     } } 
vote vote

69

With C++17 (or later), you can 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.

vote vote

50

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';     } }    

Top 3 video Explaining How can I loop through a C++ map of maps?

Related QUESTION?