Reputation: 2337
Let's say I have a vector of strings as defined below.
std::vector<std::string> names;
names.push_back( "Zero" );
names.push_back( "One" );
names.push_back( "Two" );
names.push_back( "Three" );
names.push_back( "Four" );
names.push_back( "Five" );
names.push_back( "Six" );
names.push_back( "Seven" );
names.push_back( "Eight" );
names.push_back( "Nine" );
Also, let's say I have a vector which defines which elements to loop through:
std::vector< int > indices;
indices.push_back( 0 );
indices.push_back( 5 );
indices.push_back( 6 );
How can I iterate on the vector names
according to the elements of the vector indices
to for example access names: "Zero"
, "Five"
, and "Six"
? I know that:
for( vector<string>::iterator it=names.begin() ; it < names.end(); it++)
iterate over all elements or elements for which we can find a pattern, e.g., every other element, etc. But how about iterating over elements that have no pattern or difficult to find a pattern? How can a vector be used for iteration in another vector? Something like:
for( vector<int>::iterator it=indices.begin() ; it < indices.end(); it++ )
{
names.at( indices.at( it ) )
...
}
Upvotes: 1
Views: 597
Reputation: 1305
You can also use a std::for_each
call with a lambda to access the indicies (version 1)
Furthermore, you could use a range-based for loop with rvalues
(version 2)
#include <vector>
#include <algorithm>
int main()
{
std::vector<std::string> names;
names.push_back("Zero");
names.push_back("One");
names.push_back("Two");
names.push_back("Three");
names.push_back("Four");
names.push_back("Five");
names.push_back("Six");
names.push_back("Seven");
names.push_back("Eight");
names.push_back("Nine");
std::vector< int > indices;
indices.push_back(0);
indices.push_back(5);
indices.push_back(6);
// version 1
std::for_each(std::cbegin(indices), std::cend(indices),
[&](auto &idx) { std::cout << names.at(idx) << "\n";});
// version 2
for (auto &&idx : indices)
std::cout << names.at(idx) << "\n";
return 0;
}
Upvotes: 1
Reputation: 238461
Your suggestion is almost correct. Instead of insdices.at(it)
, you should dereference the iterator. But you can do it simply like this:
for(int index : indices) {
names[index];
}
Or you can use vector::at
if you cannot prove that names.size()
> indices[i]
for all i
.
Upvotes: 3
Reputation: 44278
It is as simple as this:
for( vector<int>::iterator it=indices.begin() ; it != indices.end(); ++it )
{
names.at( *it );
names[*it]; // for faster but unvalidated access
...
}
Note: ++it
could be faster (but cannot be slower) so it is usually used when you do not care if it is postfix or prefix form. it != container.end()
also is usually used because it is more generic (less than works for random access iterator, but would not for forward iterator for example).
Upvotes: 2