¿Cómo recorrer un mapa de mapas en C ++?

¿Cómo podría recorrer un std::map en C ++? Mi mapa se define como:

 std::map< std::string, std::map > 

Por ejemplo, esto tiene datos como este:

 m["name1"]["value1"] = "data1"; m["name1"]["value2"] = "data2"; m["name2"]["value1"] = "data1"; m["name2"]["value2"] = "data2"; m["name3"]["value1"] = "data1"; m["name3"]["value2"] = "data2"; 

¿Cómo puedo recorrer este mapa y acceder a los diversos valores?

Pregunta anterior, pero las respuestas restantes están desactualizadas a partir de C ++ 11; puede usar un bucle for basado a distancia y simplemente hacer:

 std::map> 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 } } 

esto debería ser mucho más limpio que las versiones anteriores, y evita copias innecesarias.

Algunos favorecen la sustitución de los comentarios con definiciones explícitas de variables de referencia (que se optimizan si no se utilizan):

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

Puedes usar un iterador.

 typedef std::map>::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. } 
 for(std::map >::iterator outer_iter=map.begin(); outer_iter!=map.end(); ++outer_iter) { for(std::map::iterator inner_iter=outer_iter->second.begin(); inner_iter!=outer_iter->second.end(); ++inner_iter) { std::cout << inner_iter->second << std::endl; } } 

o más agradable en 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; } } 

Haz algo como esto:

 typedef std::map InnerMap; typedef std::map 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'; } } 

En C ++ 17, podrá usar la función de “enlaces estructurados”, que le permite definir múltiples variables, con diferentes nombres, utilizando una sola tupla / par. Ejemplo:

 for (const auto& [name, description] : planet_descriptions) { std::cout << "Planet " << name << ":\n" << description << "\n\n"; } 

La propuesta original (por las luminarias Bjarne Stroustrup, Herb Sutter y Gabriel Dos Reis) es divertida de leer (y la syntax sugerida es más intuitiva en mi humilde opinión); también está la redacción propuesta para el estándar que es aburrido de leer, pero está más cerca de lo que realmente entrará.

C ++ 11:

 std::map< std::string, std::map > 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; 

salida:

 name1:value1:data1 name1:value2:data2 name2:value1:data1 name2:value2:data2 name3:value1:data1 name3:value2:data2 

use std::map< std::string, std::map >::const_iterator cuando el mapa es const.