简体   繁体   中英

How can I create a 1D vector from a 2D vector in C++?

If I have a 2D vector of size nxm and I want to create a 1D vector of size n with all the elements in column 0 of 2D vector, how can I achieve this with one line of code?

Basically, I want to minimize last 3 lines of code into 1.

vector<int> res;
for (auto i:orders) res.push_back(i[1]);
return res;

orders is a 2D vector:

vector<vector<int>> orders;

This could be a way:

  • Create a new vector with a size equals to the original vector (only that this won't be a vector of vectors of int, just a vector of int).
  • Then fill it with the contents of v[row][0] , v being the original vector.

[Demo]

#include <algorithm>  // generate
#include <iostream>  // cout
#include <vector>

int main() 
{
    std::vector<std::vector<int>> v{ {1, 2}, {3, 4}, {5, 6} };
    std::vector<int> w(v.size());

    std::generate(std::begin(w), std::end(w), [row=0, &v]() mutable { return v[row++][0]; });

    for (auto&& i : w) { std::cout << i << " "; } std::cout << "\n";
}

In a bit more generic way, still using vector of vectors though:

[Demo]

#include <algorithm>  // generate
#include <iostream>  // cout
#include <vector>

template <typename T>
auto slice_column(const std::vector<std::vector<T>>& v, size_t col)
{
    std::vector<T> ret(v.size());
    std::generate(std::begin(ret), std::end(ret), [row=0, &v, &col]() mutable { return v[row++][col]; });
    return ret;
}

int main() 
{
    std::vector<std::vector<int>> v{ {1, 2}, {3, 4}, {5, 6} };
    auto w{ slice_column(v, 0) };
    for (auto&& i : w) { std::cout << i << " "; } std::cout << "\n";
}

I want to create a 1D vector of size n with all the elements in column 0 of 2D vector

This answer focuses on the above.

Create a view over the first element in each vector and return {begin(), end()} for that view to create the resulting vector from those iterators:

#include <ranges> // std::views::transform
#include <vector>

template<class T> 
std::vector<T> jimOrders(const std::vector<std::vector<T>>& orders) {
    auto view = orders | std::views::transform([](const auto& i) { return i[0]; });
    return {view.begin(), view.end()};
}

Demo

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