Extract a vector from a vector of vectors

Hi,

I have to work with medium large data files. They are anything from 1 to 1024 x 262144 doubles. Of course at any one I do not use all of them (not at the moment) I only need 262144 points at a time however I read them in in one go to a vector of vectors. I can of course use the .push_back() method to construct a new vector and return it from a method (which works well in a for loop) but I was wondering whther I could use some iterator type constructor of the new 1D vector from the 2D vector or better just to rertun a pointer to the specfic vector in the 2D vector. So far I tried this:

<auto start=twoD.begin()+slice*262144;
auto end=start+262144;
std::vector<double> new1D(start,end);>

However this does not work and throws a compile error of:
"no matching constructor for initialization of 'std::vector<double>'"

Is there way to have iterators which will work in a 1D vector constructor? What is the most effective way to return a vector from a vector of vector?

Thanks,
Z
ok! I found a solution which seems to work. this is the code

1
2
3
4
5
6
7
int wanted_row= X;
std::vector<std::vector<double> >::iterator row=twoD.begin()+ wanted_row;
std::vector<double>::iterator start=row->begin();
std::vector<double>::iterator end=row->end(); //corrected

std::vector<double> new1D(start,end);


This compiles with no error and gives the desired result but how effective is it? is it better than a for loop with push_back-s?

Thanks,
Z
Last edited on
line 4 should be named end, not start.

Directly initializing a a 1D vector from one of the vector elements in the 2D array is another way to copy the data:

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <vector>
#include <numeric>

template <typename T>
std::ostream& operator<<(std::ostream&, const std::vector<std::vector<T>>&);

template <typename T>
std::ostream& operator<<(std::ostream&, const std::vector<T>&);

int main()
{
   unsigned row_size { 3 };
   unsigned col_size { 4 };

   std::vector<std::vector<int>> vec(row_size, std::vector<int>(col_size));

   // initialize the vector with some values other than zero
   int start  { 101 };
   int offset { 100 };

   for (auto& itr : vec)
   {
      std::iota(itr.begin(), itr.end(), start);
      start += offset;
   }

   std::cout << vec << '\n';

   // let's get a couple of iterators to the 2nd row
   auto itr_beg { vec[1].begin() };
   auto itr_end { vec[1].end() };

   for (auto itr = itr_beg; itr != itr_end; itr++)
   {
      std::cout << *itr << ' ';
   }
   std::cout << "\n\n";

   // directly intialize a 1D vector from one of the vectors in the 2D vector
   std::vector<int> anotherVec { vec[2] };

   std::cout << anotherVec << "\n\n";

   // assigning alwo works
   anotherVec = vec[1];

   std::cout << anotherVec << '\n';
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<T>>& v)
{
   for (auto const& x : v)
   {
      os << x << '\n';
   }

   return os;
}


template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
{
   for (auto const& x : v)
   {
      os << x << ' ';
   }

   return os;
}

101 102 103 104
201 202 203 204
301 302 303 304

201 202 203 204

301 302 303 304

201 202 203 204

1
2
3
4
5
6
7
8
9
10
11
std::vector< std::vector<double> > twoD ;
// populate twoD

std::size_t wanted_row = X ;
// assert( wanted_row < twoD.size() ) ;

// reference
std::vector<double>& new1D = twoD[wanted_row] ;

// or if we want to make a copy
std::vector<double> new1D_cpy = twoD[wanted_row] ;

Thanks for the great examples. Nice. All of them work like charm.
Topic archived. No new replies allowed.