Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge vector of vectors into a single vector

Tags:

I have vector of vectors of T:

std::vector<std::vector<T>> vector_of_vectors_of_T; 

I want to merge all of them into single vector of T:

std::vector<T> vector_of_T; 

I am currently using this method:

size_t total_size{ 0 }; for (auto const& items: vector_of_vectors_of_T){     total_size += items.size(); } vector_of_T.reserve(total_size); for (auto const& items: vector_of_vectors_of_T){     vector_of_T.insert(end(vector_of_T), begin(items), end(items)); } 

Is there more straightforward method? Like a ready std function? If not, is there more efficient way to do it manually?

like image 797
Humam Helfawi Avatar asked Feb 09 '16 09:02

Humam Helfawi


People also ask

How do you combine vectors together?

The concatenation of vectors can be done by using combination function c. For example, if we have three vectors x, y, z then the concatenation of these vectors can be done as c(x,y,z). Also, we can concatenate different types of vectors at the same time using the same same function.

How do you flatten a vector in C++?

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.

What is append vector?

Appending to a vector means adding one or more elements at the back of the vector. The C++ vector has member functions. The member functions that can be used for appending are: push_back(), insert() and emplace(). The official function to be used to append is push_back().

Can you add a vector to another vector?

To insert/append a vector's elements to another vector, we use vector::insert() function.


1 Answers

It's a nice exercise to try and write up a generic join. The code below takes a nested container R1<R2<T> and returns a joined container R1<T>. Note that because of the allocator parameters in the Standard Library, this is a bit cumbersome. No attempt is being made to check for allocator compatibility etc.

Fortunately, there's action::join function in the upcoming range-v3 library by Eric Niebler, that is quite robust already and works today on Clang:

#include <range/v3/all.hpp> #include <algorithm> #include <iostream> #include <iterator> #include <numeric> #include <vector>  // quick prototype template<template<class, class...> class R1, template<class, class...> class R2, class T, class... A1, class... A2> auto join(R1<R2<T, A2...>, A1...> const& outer) {     R1<T, A2...> joined;     joined.reserve(std::accumulate(outer.begin(), outer.end(), std::size_t{}, [](auto size, auto const& inner) {         return size + inner.size();     }));     for (auto const& inner : outer)         joined.insert(joined.end(), inner.begin(), inner.end());     return joined; }  int main() {     std::vector<std::vector<int>> v = { { 1, 2 }, { 3, 4 } };      // quick prototype     std::vector<int> w = join(v);     std::copy(w.begin(), w.end(), std::ostream_iterator<int>(std::cout, ",")); std::cout << "\n";      // Eric Niebler's range-v3     std::vector<int> u = ranges::action::join(v);     std::copy(u.begin(), u.end(), std::ostream_iterator<int>(std::cout, ",")); std::cout << "\n"; } 

Live Example

like image 99
TemplateRex Avatar answered Sep 30 '22 06:09

TemplateRex