0

I have a std::vector as described below:

std::vector<std::pair<int, const char*>> matrix;

This vector has the following values (for e.g.): values (as an example)

These values can be access here as follows:

matrix[0] = [0,Hello] // pseudo code (only showing values inside)

matrix[1] = [0,Fox]  // pseudo code (only showing values inside)

matrix[2] = [1,Red]  // pseudo code (only showing values inside)

I am iterating through the contents of the vector read the values, by doing this:

    for (std::vector<std::pair<int, const char*>>::iterator it = matrix.begin(); it != matrix.end(); ++it) 
    {
        std::pair<int, const char*> v_temp = *it;
        std::cout << v_temp.first;
        std::cout << v_temp.second;
    }

Now, what this is doing is iterating from the first element of vector to the end element of the vector. What I want to do, is iterate only on the first elements (i.e. int values). So, from the tabular image I have attached, this current code will loop for [ row x column ] [ 9 x 2] = 18 times. What I want it for it to iterate only 9 times [ rows ] and not consider columns at-all.

How can I do that?

cryengineplus
  • 61
  • 1
  • 3

3 Answers3

3

There are a lot of ways to skin this particular cat. One would be to use std::transform:

std::transform(v.begin(), v.end(),
    std::ostream_iterator<int>(std::cout, "\t"),
    [](auto const &p) { return p.first; });
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
3

TL;DR boost::transform_iterator is your friend.

Example taken from What is the equivalent of boost::make_transform_iterator in the standard library?:

// I couldn't realize how to specialize type of std::get, so I need this helper.
inline int tuple_fst(const std::tuple<int, const char*> &x) {
  return x.first;
}
...
auto beg = boost::make_transform_iterator(matrix.begin(), tuple_fst);
auto end = boost::make_transform_iterator(matrix.end(), tuple_fst);
for (auto it = beg; it != end; ++it) {
    std::cout << *it;
}

This is actually a nice question, I don't understand why it is so downvoted. You wanted something like rust's std::iter::Map or Haskell's map. Unfortunately, in C++ things get a bit more ugly if you want high level iterator functions.

pallly
  • 629
  • 5
  • 13
0

Your loop iterates over the rows of the matrix. Element iof matrix is the "row" at index i (in this case a std::pair<int, const char*>. So if you have pushed back 9 pairs then the loop will iterate 9 times.

FYI: You can simplify your code using the C++ feature auto:

for(auto it = matrix.begin(); it != matrix.end(); ++it){
    auto v_temp = *it;
    std::cout << v_temp.first;
    std::cout << v_temp.second;
}

A further simplification is

for(const auto& v_temp : matrix)
{
    std::cout << v_temp.first;
    // ...
}

You can use the C++11 for-range based loop for any object on which the compiler can call begin() and end() on.

jensa
  • 2,792
  • 2
  • 21
  • 36