Phorce
Phorce

Reputation: 4642

C++ pushing elements of a vector of vectors into a vector

I'm just wondering whether there is a simple, quick way to insert the elements of a vector of vectors inside a vector.

For example:

std::vector<std::vector<double> > vals
{

    {1, 2, 3, 4, 5, 6},
    {1, 2, 3, 4, 5, 6}
};
std::vector<double> myvector;

so myvector would then contain: 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6

I've tried using insert and push_back but had no luck.

Edit:

I have used:

myvector.insert(vals.begin(), vals.end()); - No matching member function to call to 'insert'

Upvotes: 3

Views: 10528

Answers (5)

Thomas Young
Thomas Young

Reputation: 195

Depending on how your vector of vectors is built in the first place, there may be a more efficient way to approach this.

If your sub-vectors are all the same length (as appears to be the case from the code example), then the best thing may be to view myvector as a 2D array and build directly into this buffer.

If the sub-vector lengths can vary, but the code that builds your vector of vectors only ever actually adds stuff at the end, then you can use something like the 'collapsed vector vector' class I describe here to build this data, instead of a vector of vectors. (And after that, again, your data is already in the kind of contiguous buffer you are looking for.)

Either way, if performance or memory footprint are important here then avoiding the vector of vector construct can eliminate a lot of buffer manipulation overhead, and work out as quite a significant optimisation.

Upvotes: 2

Zac Howland
Zac Howland

Reputation: 15872

If you want to insert all of the elements of vals into a single vector:

Brute Force Method

for (int i = 0; i < vals.size(); ++i)
{
    for (int j = 0; j < vals[i].size(); ++j)
    {
        myvector.push_back(vals[i][j]);
    }
}

More Elegant Method

struct AddVector
{
    std::vector<double> myvector;
    void operator()(const std::vector<int>& a)
    {
        std::copy(a.begin(), a.end(), std::back_inserter(myvector));
    }
};

// somewhere in your code
AddVector av;
std::for_each(vals.begin(), vals.end(), av);
myvector.swap(av.myvector);

Upvotes: 1

RedX
RedX

Reputation: 15175

Try

// c++11
for(auto && v : vals){
  myvector.insert(myvector.end(), v.begin(), v.end());
}

// non c++11
for(std::vector<std::vector<double> >::const_iterator it = vals.begin(), end = vals.end(); it != end; ++it){
  myvector.insert(myvector.end(), it->begin(), it->end());
}

Upvotes: 10

Enigma
Enigma

Reputation: 1717

resize myvector to the size of the sum of the sizes of the vectors in vals. For every vector in vals concat it to myvector. To get a idea how to concat:

Concatenating two std::vectors

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409176

The variable vals is a vector of vectors, but myvector is a vector of doubles. Trying to insert from the first into the second will not work as the contained types are different (std::vector<double> versus double).

Instead you have to manually insert from each sub-vector of vals into myvector.

Upvotes: 0

Related Questions