Rasmus Damgaard Nielsen - 1 year ago 150
C++ Question

# Generic method for flattening 2d vectors

I have a function to flatten out an vector of vectors to a single vector. Comming from c# i would write it something like:

``````vector<T> flatten(vector<vector<T>> 2dVector)
{
vector<T> newVector(2dVector.size()*2dVector[0].size())
for (int i = 0; i < 2dVector.size(); i++)
{
for (int j = 0; j < 2dVector[i].size(); j++)
{
newVector[j + i * 2dVector.size()] = 2dVector[i][j];
}
}
return newVector;
}
``````

but this code gives 20+ errors in msvc++

After hours of seaching the web for how to make this function, i modified the method signature to

utilities.h:

``````template <typename A, typename B> A flatten(const B 2dVector&);
``````

utilities.cpp:

``````template <typename A, typename B> A flatten(const B 2dVector&)
{
A newVector(2dVector.size()*2dVector[0].size())
for (int i = 0; i < 2dVector.size(); i++)
{
for (int j = 0; j < 2dVector[i].size(); j++)
{
newVector[j + i * 2dVector.size()] = 2dVector[i][j];
}
}
return newVector;
}
``````

But i still get on the order of ~15 errors from this code, and i am all out of ideas. Any suggestions?

Your code contains several problems. To name a few:

2. Your template should be parameterized by a single parameter - the basic value type of the returned vector
3. Your code internally assumes that the vectors are same-sized, where it is just as easy to accommodate a ragged array
4. There are more efficient ways to append a vector to the end of a vector.

I'd suggest the following alternative:

``````#include <vector>

template<typename T>
std::vector<T> flatten(const std::vector<std::vector<T>> &orig)
{
std::vector<T> ret;
for(const auto &v: orig)
ret.insert(ret.end(), v.begin(), v.end());
return ret;
}

int main()
{
std::vector<std::vector<int>> vv;
vv.push_back(std::vector<int>{1, 2, 3});
vv.push_back(std::vector<int>{10, 20});
flatten(vv);
}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download