libreria how example ejemplo c++ loops dictionary iteration idioms

how - string map c++



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

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

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

Por ejemplo, esto contiene 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?


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;

salida:

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


En C ++ 17, podrá utilizar la función "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 sintaxis sugerida es IMHO más intuitiva); 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á.


Haz algo como esto:

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


Pregunta anterior, pero las respuestas restantes están desactualizadas en C ++ 11; puede usar un rango basado en bucle para hacer simplemente lo siguiente:

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

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

Algunos prefieren sustituir 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<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. }


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


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

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