¿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
cuando el mapa es const.