开发者

Create vector of sizes of the vectors inside a "2d-vector" (vector< vector<> >)?

开发者 https://www.devze.com 2023-03-27 01:29 出处:网络
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

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消