4

What is a good way to convert vector<vector<int>> vint to vector<vector<double>>vdouble?

I know from C++ convert vector<int> to vector<double> that this can be done for 1-D but I am not too sure how to do it for 2-d case.

Community
  • 1
  • 1
dimsum204
  • 53
  • 4

4 Answers4

6

Here's a pretty simple solution which uses emplace_back and the vector range constructor:

std::vector<std::vector<int>> intvec;
//intvec filled somehow

std::vector<std::vector<double>> doublevec;
doublevec.reserve(intvec.size());
for (auto&& v : intvec) doublevec.emplace_back(std::begin(v), std::end(v));
Andrew
  • 5,212
  • 1
  • 22
  • 40
TartanLlama
  • 63,752
  • 13
  • 157
  • 193
3
#include <iostream>                                                                                                                                                                                                                         
#include <vector>
#include <algorithm>

double castToDouble(int v) {
    return static_cast<double>(v);
}

int main() {
    std::vector<std::vector<int>> intv;
    std::vector<std::vector<double>> doublev;

    std::transform(intv.begin(), intv.end(), std::back_inserter(doublev), [](const std::vector<int> &iv) {
        std::vector<double> dv;
        std::transform(iv.begin(), iv.end(), std::back_inserter(dv), &castToDouble);
        return dv;
    });

    return 0;
}
VP.
  • 15,509
  • 17
  • 91
  • 161
  • Nice Solution also this is appliable to other numerical type 2d to 2d vector conversion problems with a little tweak in the cast function – Amir Rasti Aug 31 '23 at 18:24
0

The naive solution is to use two loops, one nested inside the other, preferably range-based for loops.

You could also use e.g. std::transform with a lambda expression that in turn also calls std::transform on the nested vector, which does the actual conversion.

If you use std::transform remember to set the size of the destination vector, or use e.g. std::back_inserter.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

A simple way is with std::transform and the range constructor of std::vector. If you're using back_inserter, you should reserve() some capacity to avoid repeated reallocations.

Live example: http://coliru.stacked-crooked.com/a/84ef0e3d6572792a

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
    std::vector<std::vector<int>> vvi = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    std::vector<std::vector<double>> vvd;
    vvd.reserve(vvi.size());

    std::transform(begin(vvi), end(vvi), std::back_inserter(vvd),
                   [](const std::vector<int>& vi) {
                       return std::vector<double>(begin(vi), end(vi));
                   });

    // Output the destination container for verification:
    for_each(begin(vvd), end(vvd), [](const std::vector<double>& vd){
        std::copy(begin(vd), end(vd), std::ostream_iterator<double>(std::cout, " "));
        std::cout << "\n";});
}
Andrew
  • 5,212
  • 1
  • 22
  • 40