C++ Maps
Oct 23, 2012 at 6:06pm UTC
Hi, I am having difficultly understanding how to print the value of the vector inside a map.
1 2 3 4 5 6 7 8 9 10
map<string,vector<string> > test;
map<string,vector<string> >::iterator itr;
for (itr = test.begin(); itr != test.end(); itr++)
{
for (int i = 0; i != itr->second.size(); i++)
{
cout << itr->second[i] << endl;
}
}
This is what I have but it just seem strange. Is their a better method?
Oct 23, 2012 at 6:35pm UTC
You could use iterators for vectors too:
1 2 3 4 5
for (vector<string>::const_iterator vi = itr->second.begin();
vi != itr->second.end();
++vi
)
cout << *vi << endl;
If you're using Visual Studio 2010+, or GNU GCC 4.6+, they may offer support for C++11's range based
for loop, and
auto matic type inference.
Then your code could look like:
1 2 3 4 5
map<string, vector<string> > test;
for (auto aPair: test)
for (string s: aPair.second)
cout << s << endl;
Disclaimer: code not tested, yet.
Oct 23, 2012 at 6:51pm UTC
Unfortunately, range-based fors didn't turn up with Visual Studio 2010. But they are there in 2012.
Last edited on Oct 23, 2012 at 7:05pm UTC
Oct 23, 2012 at 7:01pm UTC
So it would always have to be a nested loop in order to get the value in the vector?
Oct 23, 2012 at 7:32pm UTC
Well, yes. But the loops don't have to actually be nested, or even your own. For example, you could factor out the vector output code into a helper function?
1 2 3 4 5 6 7 8
template <typename TElem>
inline void write_vector(ostream& os, const vector<TElem>& vec) {
typedef vector<TElem>::size_type size_type;
const size_type size = vec.size();
for (size_type i = 0; i < size; ++i) {
os << vec[i] << endl;
}
}
and then use it like
1 2 3 4
typedef map<string,vector<string> >::iterator iter_type;
for (iter_type itr = test.begin(), itr_end = test.end(); itr_end != itr; ++itr) {
write_vector(cout, itr->second);
}
or use an algorithm
1 2 3 4 5 6
typedef map<string, vector<string> >::iterator iter_type;
for (iter_type itr = test.begin(), itr_end = test.end(); itr_end != itr; ++itr) {
const vector<string>& vec = itr->second;
ostream_iterator<string> out_it(cout, "\n" );
copy( vec.begin(), vec.end(), out_it);
}
or even use a iterative solution?
1 2 3 4 5 6 7
template <typename TIter>
inline void write_iteratively(TIter itr, const TIter itr_end, ostream& os) {
if (itr != itr_end) {
os << *itr << endl;
write_iteratively(itr + 1, itr_end, os);
}
}
used like this
1 2 3 4 5
typedef map<string, vector<string> >::iterator iter_type;
for (iter_type itr = test.begin(), itr_end = test.end(); itr_end != itr; ++itr) {
const vector<string>& vec = itr->second;
write_iteratively(vec.begin(), vec.end(),cout);
}
Last edited on Oct 23, 2012 at 7:39pm UTC
Oct 23, 2012 at 7:37pm UTC
... well you could use the horrible
std::for_each() from the
algorithm library, together with C++11 lambdas.
(Prepare a barf bag.)
1 2 3 4 5 6 7 8 9 10 11
#include <algorithm>
// ...
for_each(test.begin(), test.end(), [](decltype (*test.begin()) aPair) {
for_each(aPair.second.begin(), aPair.second.end(), [](string s) {
cout << s << ' ' ;
});
cout << endl;
});
Oct 24, 2012 at 2:01am UTC
Thank You all for the help I understand it now.
Topic archived. No new replies allowed.