Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I traverse/iterate an STL map?

I want to traverse an STL map. I don't want to use its key. I don't care about the ordering, I just look for a way to access all elements it contains. How can I do this?

like image 213
atoMerz Avatar asked Nov 17 '10 17:11

atoMerz


People also ask

How do you traverse a key on a map C++?

std::map<type,type>::iterator iter = myMap. begin(); std::map<type,type>::iterator endIter = myMap. end(); for(; iter != endIter; ++iter) { type key = iter->first; ..... }


2 Answers

Yes, you can traverse a Standard Library map. This is the basic method used to traverse a map, and serves as guidance to traverse any Standard Library collection:

C++03/C++11:

#include <cstdlib> #include <map> #include <string> using namespace std;  int main() {     typedef map<int,string> MyMap;     MyMap my_map;     // ... magic      for( MyMap::const_iterator it = my_map.begin(); it != my_map.end(); ++it )     {       int key = it->first;       string value = it->second;     } } 

If you need to modify the elements:

  • Use iterator rather than const_iterator.
  • Instead of copying the values out of the iterator, get a reference and modify the values through that.

    for( MyMap::iterator it = my_map.begin(); it != my_map.end(); ++it ) { int key = it->first; string& value = it->second; if( value == "foo" ) value = "bar"; }

This is how you typically traverse Standard Library containers by hand. The big difference is that for a map the type of *it is a pair rather than the element itself

C++11

If you have the benefit of a C++11 compiler (for example, latest GCC with --std=c++11 or MSVC), then you have other options as well.

First you can make use of the auto keyword to get rid of all that nasty verbosity:

#include <cstdlib> #include <map> #include <string> using namespace std;  int main() {     map<int,string> my_map;     // ... magic      for( auto it = my_map.begin(); it != my_map.end(); ++it )     {       int key = it->first;       string& value = it->second;     } } 

Second, you can also employ lambdas. In conjunction with decltype, this might result in cleaner code (though with tradeoffs):

#include <cstdlib> #include <map> #include <string> #include <algorithm> using namespace std;  int main() {     map<int,string> my_map;     // ... magic      for_each(my_map.begin(), my_map.end(), [](decltype(*my_map.begin()) val)     {         string& value = val.second;         int key = val.first;     }); } 

C++11 also instroduces the concept of a range-bases for loop, which you may recognize as similar to other languages. However, some compilers do not fully support this yet -- notably, MSVC.

#include <cstdlib> #include <map> #include <string> #include <algorithm> using namespace std;  int main() {     map<int,string> my_map;     // ... magic      for(auto val : my_map )     {         string& value = val.second;         int key = val.first;     } } 
like image 74
John Dibling Avatar answered Oct 01 '22 12:10

John Dibling


As with any STL container, the begin() and end() methods return iterators that you can use to iterate over the map. Dereferencing a map iterator yields a std::pair<const Key, Value>.

like image 25
fredoverflow Avatar answered Oct 01 '22 12:10

fredoverflow