Flatten a vector of vectors in C++
This post will discuss how to flatten a vector of vectors in C++.
1. Using std::insert
function
A simple solution is to iterate over the vector of vectors and insert the contents of each vector into a new vector using the std::insert
function. It is overloaded to accept a range of elements to insert at the specified position, in the same order. A typical implementation of this approach would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <iostream> #include <vector> template<typename T> std::vector<T> flatten(std::vector<std::vector<T>> const &vec) { std::vector<T> flattened; for (auto const &v: vec) { flattened.insert(flattened.end(), v.begin(), v.end()); } return flattened; } int main() { std::vector<std::vector<int>> vec { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8, 9 } }; std::vector<int> flattened = flatten(vec); for (int &i: flattened) { std::cout << i << ' '; } return 0; } |
Output:
1 2 3 4 5 6 7 8 9
2. Using Nested Loop
Another option to flatten a nested vector is using the nested for loop. The idea is to pick every element using a nested for-loop and push add it at the end of a new vector. Here’s what the code would look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include <iostream> #include <vector> #include <algorithm> template<typename T> std::vector<T> flatten(std::vector<std::vector<T>> const &vec) { int size = 0; for (auto &v: vec) { size += v.size(); } std::vector<T> flattened; flattened.reserve(size); for (auto &v: vec) { for (auto &e: v) { flattened.push_back(e); } } return flattened; } int main() { std::vector<std::vector<int>> vec { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8, 9 } }; std::vector<int> flattened = flatten(vec); for (int &i: flattened) { std::cout << i << ' '; } return 0; } |
Output:
1 2 3 4 5 6 7 8 9
3. Using std::accumulate
Another option to flatten a vector of vectors is using the standard function std::accumulate
, defined in the header <numeric>
. We can overwrite its default operation by providing a binary predicate in the optional fourth parameter, which performs the flatten operation on two vectors and return the flattened list.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> #include <vector> #include <numeric> int main() { std::vector<std::vector<int>> vec { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; auto flattened = std::accumulate(vec.begin(), vec.end(), decltype(vec)::value_type{}, [](auto &x, auto &y) { x.insert(x.end(), y.begin(), y.end()); return x; }); for (int &i: flattened) { std::cout << i << ' '; } return 0; } |
Output:
1 2 3 4 5 6 7 8 9
4. Using range-v3 library
Here’s a one-liner using the ranges::views::join
function from ranges-v3 library, which forms the basis for C++20’s std::ranges
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <vector> #include <range/v3/view/join.hpp> #include <range/v3/range/conversion.hpp> int main() { std::vector<std::vector<int>> vec { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8, 9 } }; auto flattened = ranges::views::join(vec); for (int &i: flattened) { std::cout << i << ' '; } return 0; } |
Output:
1 2 3 4 5 6 7 8 9
That’s all about flattening a vector of vectors in C++.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)