I have a vector of vectors, say
std::vector< std::vector<int> > my2dArray;
Now I would like to have a vector that contains the sizes of the vectors inside my2dArray
. Manually this would look something like
std::vector<int> mySizes;
for (int i = 0; i < my2dArray.size(); i++ )
{
mySizes.push_back( my2dArray[i].size() );
}
Is there a more "elegant" way of doing this - without manually writing a loop - by making use of some STL algorithm or the lik开发者_StackOverflow社区e?
C++03:
typedef std::vector<int> IntVec;
std::vector<size_t> sizes(my2dArray.size());
std::transform(my2dArray.begin(), my2dArray.end(), sizes.begin(),
std::mem_fun_ref(&IntVec::size));
About the best you're gonna get (C++11 required)
std::vector<int> mySizes(my2dArray.size());
auto getSize = [](const std::vector<int> & v) { return v.size(); };
std::transform(my2dArray.begin(), my2dArray.end(), mySizes.begin(), getSize);
It's not really a huge improvement, and if you can't use lambdas, I don't think the extra trouble would be worth it.
This works. I tried to have the sizeVec as a member of Sizes but that didn't work as discussed in this question.
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
class Sizes
{
public:
Sizes( std::vector<int>& v ) : sizeVec( v ) {}
void operator() ( std::vector<int>& v ) {
sizeVec.push_back( v.size() );
}
std::vector<int>& sizeVec;
};
void outFunc (int i) {
std::cout << " " << i;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<std::vector<int>> twodVec;
std::vector<int> vec;
vec.push_back( 6 );
twodVec.push_back( vec );
vec.push_back( 3 );
twodVec.push_back( vec );
vec.push_back( 8 );
twodVec.push_back( vec );
vec.push_back( 3 );
twodVec.push_back( vec );
std::vector<int> sizeVec;
Sizes sizes(sizeVec);
std::for_each( twodVec.begin(), twodVec.end(), sizes );
std::for_each( sizeVec.begin(), sizeVec.end(), outFunc );
return 0;
}
EDIT : The question I asked about this has been answered by Oli Charlesworth; you can change the object to:
class Sizes
{
public:
void operator() ( std::vector<int>& v ) {
sizeVec.push_back( v.size() );
}
std::vector<int> sizeVec;
};
And then in main:
Sizes sizes;
sizes = std::for_each( twodVec.begin(), twodVec.end(), sizes );
std::for_each( sizes.sizeVec.begin(), sizes.sizeVec.end(), outFunc );
if you prefer. If you have boost you'll be able to use Boost.Ref to make is even simpler.
EDIT 2: changed the functor to receive the vector by reference rather than value as suggested by Alf P Steinbach in the question I asked about this.
精彩评论