Перебрать вектор, используя только первое значение std::pair

У меня есть std::vector, как описано ниже:

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

Этот вектор имеет следующие значения (например): values ​​(как пример)

Эти значения могут быть доступны здесь следующим образом:

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)

Я перебираю содержимое вектора, читая значения, делая это:

    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;
    }

Теперь это итерация от первого элемента вектора к конечному элементу вектора. Что я хочу сделать, так это перебирать только первые элементы (т.е. значения int). Итак, из табличного изображения, которое я приложил, этот текущий код будет зацикливаться на [строка x столбец] [9 x 2] = 18 раз. Я хочу, чтобы он выполнял итерацию только 9 раз [строки] и вообще не учитывал столбцы.

Как я могу это сделать?


person cryengineplus    schedule 18.12.2015    source источник
comment
Вы пытались удалить строку std::cout << v_temp.second;?   -  person Yakk - Adam Nevraumont    schedule 19.12.2015
comment
Возможно, вы захотите узнать, как использовать какой-нибудь инструмент отладчик, чтобы понять поток управления вашей программы лучше   -  person Ivan Aksamentov - Drop    schedule 19.12.2015


Ответы (3)


Есть много способов снять шкуру с этой конкретной кошки. Можно было бы использовать std::transform:

std::transform(v.begin(), v.end(),
    std::ostream_iterator<int>(std::cout, "\t"),
    [](auto const &p) { return p.first; });
person Jerry Coffin    schedule 19.12.2015

Ваш цикл перебирает строки матрицы. Элемент iof matrix — это «строка» с индексом i (в данном случае std::pair<int, const char*>). Таким образом, если вы отодвинули назад 9 пар, цикл повторится 9 раз.

К вашему сведению: вы можете упростить свой код с помощью функции C++ auto:

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

Дальнейшее упрощение

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

Вы можете использовать цикл for-range C++11 для любого объекта, для которого компилятор может вызывать begin() и end().

person jensa    schedule 18.12.2015
comment
Вы можете упростить его с помощью for(auto& v_temp: matrix) { ... } - person Kevin; 19.12.2015
comment
@Кевин Действительно! Я добавлю это к ответу. - person jensa; 19.12.2015

TL;DR boost::transform_iterator твой друг.

Пример взят из Что эквивалентно boost::make_transform_iterator в стандартной библиотеке?:

// 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;
}

На самом деле это хороший вопрос, я не понимаю, почему за него так проголосовали. Вы хотели что-то вроде std::iter::Map в ржавчине или map в Haskell. К сожалению, в C++ все становится немного уродливее, если вам нужны функции итератора высокого уровня.

person pallly    schedule 22.03.2020