0

I have a problem iterating over the second map in a map.

#include <map> using namespace std; map<string, map<string, string> > mymap; map<string, map<string, string> >::iterator itm; pair<map<string, map<string, string> >::iterator,bool> retm; for( itm=mymap.begin(); itm!=mymap.end(); ++itm) { cout << "first:\t" << it->first << endl; } 

How can I iterate over the second map and get both first and second keys/values?

And the second question is, how can I "insert" into the first and second map using the "insert" function that comes with maps?

I hope someone has a full answer.

5 Answers 5

4

it->second will give you the "second map". Just iterate over that.

Sign up to request clarification or add additional context in comments.

Comments

3
#include <map> #include <iostream> using namespace std; map<string, map<string, string> > mymap; map<string, map<string, string> >::iterator itm; pair<map<string, map<string, string> >::iterator,bool> retm; int main() { /* populate: */ mymap.insert(make_pair ("something", map<string, string>())); mymap["something"].insert(make_pair ("2", "two")); /* traverse: */ for( itm=mymap.begin(); itm!=mymap.end(); ++itm) { cout << "first:\t" << itm->first << endl; for (map<string, string>::iterator inner_it = (*itm).second.begin(); inner_it != (*itm).second.end(); inner_it++) { cout << (*inner_it).first << " => " << (*inner_it).second << endl; } } return 0; } 

4 Comments

@Martin: OK, but that's true of most SO questions. That's usually why they are questions...
This question is clearly asking two things: how do you generally access the inner map; and how do you insert a new element. They're not asking about the it/itm typo.
Thanks for this answer. This is about the whole answer. I will upvote it. If I could I would upvote perreal, Kerrek SB and Martin's answers.
Oh, apologies, I had misread there to be a typedef, when actually itm is an object!
2

You will need a second iterator in an additional nested for-loop to iterate over the it->second just like you iterated over mymap.

Comments

2

Like this:

typedef std::map<std::string, std::map<std::string, std::string>>::iterator outer_it; typedef std::map<std::string, std::string>::iterator inner_it; for (outer_it it1 = mymap.begin(); it1 != mymap.end(); ++it1) { for (inner_it it2 = it1->second.begin(); it2 != it1->second.end(); ++it2) { std::cout << "first: " << it1->first << ", second: " << it2->first << ", value: " << it2->second << std::endl; } } 

To insert:

mymap["hello"]["world"] = "foo"; 

Or, using insert:

mymap["hello"].insert(std::make_pair("world", "foo")); 

If you want to insert multiple values, perform the outer lookup only once:

std::map<std::string, std::string> & m = mymap["hello"]; m.insert(std::make_pair("world", "foo")); m.insert(std::make_pair("word", "boo")); m.insert(std::make_pair("lord", "coo")); 

3 Comments

Yes but I meant using the map::insert function. But I very much like what you did with the first part. Thanks. :)
@perreal: Thanks, fixed -- I had misread a typedef in the OP's code when actually there wasn't any!
@user1058431: I added some information on avoiding repeated, redundant look-ups.
1

In C++11, you can do it like this:

for (const auto& outerElem: mymap) { cout << "First: " << outerElem.first << endl; for (const auto& innerElem: outerElem.second) { cout << " First: " << innerElem.first << endl; cout << " Second: " << innerElem.second << endl; } } 

In C++03, you can also do this with BOOST_FOREACH. You cannot use auto though, so it's best to typedef each type like this. Using typedefs like this is a good idea anyway.

typedef map<string, string> innerMap; typedef map<string, innerMap> outerMap; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.