简体   繁体   中英

Converting std::vector<std::vector<std::string>> to std::vector<std::vector<double>>

Is it possible to iterate through a two-dimensional vector of strings and convert the strings into doubles? If so, what would be the best method of doing so? I'm fairly inexperienced with two-dimensional vectors and iterators, so I apologize if this has been asked before. I attempted to find a solution but I didn't have much luck.

This is a small sample of my 2-dimensional vector input:

图片

I attempted to iterate through my two-dimensional vector in the code below in hopes that I could use std::stod() to parse the strings and convert them into doubles, but it didn't work.

// Here is my original vector which I filled by taking input from a csv file
std::vector<std::vector<std::string>> original_matrix;

std::vector<std::vector<double>> doubles_matrix;
doubles_matrix.reserve(original_matrix.size());
for(auto beg = original_matrix.begin(); beg != original_matrix.end(); ++beg)
{
    for(auto ceg = beg->begin(); ceg != beg->end(); ++ceg) {

    }
}

First of all. There are one million solutions for your problem. Everbody can use what he wants. Styles are different. Newbies generally like C-Style solutions more than sophisticated and "modern C++" solution.

Im my very humble opinion, (only my personal opinion) the answer from user "super" (+1) is by far better as the accepted answer from user "selbie". But OP accepted it and hence, it is the most fitting answer for OP.

I would like to show an additional solution, which is the same as from user "super", just using "more-modern" C++ elements.

You have a 2 dimensional std::vector . That is a very good approach. Now you want to transform this std::vector of std::vector of std::string into a different data type. You even used the tag "transform" in your question.

For such transformation, you could use a function from the C++ library that has been made for excactly this purpose. It is called std::transform .

It transforms elements from a container into something different. It iterates over each element in a container and then uses a "function", eg a lambda, to transform that element.

With 2 dimensional vectors, we need to apply std::transform for each dimension.

And because such a dedicated function is existing in C++, I would recommend to use it.

See the below example:

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

int main() {

    // The source data
    std::vector<std::vector<std::string>> vvs{ {"1","2","3","4"},{"5","6","7","8"},{"9","10","11","12"},{"13","14","15","16"}};

    // Here we will store the result
    std::vector<std::vector<double>> vvd{};

    // Transform 2 dimensional vector
    // Outer vector
    std::transform(vvs.begin(), vvs.end(), std::back_inserter(vvd), [](const std::vector<std::string>&vs) {
        std::vector<double> vd{};
        // Inner vector
        std::transform(vs.begin(), vs.end(), std::back_inserter(vd), [](const std::string& s) { return std::stod(s); });
        return vd;
        });

    // Show debug output
    std::for_each(vvd.begin(), vvd.end(), [](const std::vector<double>& vd) {
        std::copy(vd.begin(), vd.end(), std::ostream_iterator<double>(std::cout, " ")); std::cout << "\n"; });

    return 0;
}

But, as said, everybody can do, what he wants.

#include <vector>
#include <string>

auto convertVector(std::vector<std::vector<std::string>>& stringVec) {
    std::vector<std::vector<double>> output;
    for (auto& vec : stringVec) {
        output.push_back({});
        for (auto& str : vec) {
            output.back().push_back(std::stod(str));
        }
    }

    return output;
}

Converting a string to double is done with the strtod function:

string s = 3.14;
double d = strtod(s.c_str(), nullptr);

Then apply the above my looping of the vectors any way you want. Here's an example:

void convert(const vector<vector<string>>& stringVectors, vector<vector<double>>& doubleVectors)
{
    doubleVectors.clear();
    doubleVectors.resize(stringVectors.size());

    for (size_t i = 0; i < stringVectors.size(); i++) {
        auto& vs = stringVectors[i];
        auto& vd = doubleVectors[i];
        vd.resize(vs.size());
        for (size_t j = 0; j < vs.size(); j++) {
            vd[j] = strtod(vs[j].c_str(), nullptr);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM