Как я могу получить текущую позицию без другой переменной? - PullRequest
2 голосов
/ 15 марта 2012

Часто при создании грамматического списка (с запятыми) я использую код, подобный следующему:

std::stringstream list;
int i = 0;
for (auto itemListIt = itemList.begin(); itemListIt != itemList.end(); itemListIt++)
{
    list << *itemListIt;
    if (i < itemList.size() - 1) list << ", ";
    i++;
}

Есть ли какой-нибудь более краткий способ сделать это, возможно, без дополнительной переменной - 'i'

Ответы [ 5 ]

3 голосов
/ 15 марта 2012

Почему бы не проверить то, что вам действительно интересно; «Есть ли еще один элемент после этого?».

std::stringstream list;
for (auto it = roomList.begin(); it != itemList.end(); it++)
{
    list << *it;
    if ( it+1 != itemList.end() ) list << ", ";
}
1 голос
/ 15 марта 2012

Вы можете циклически перебирать все с точностью до последнего, используя --items.end().

Затем выведите последний, используя items.back().

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

int main()
{
    std::ostringstream oss;

    std::vector<int> items;
    items.push_back(1);
    items.push_back(1);
    items.push_back(2);
    items.push_back(3);
    items.push_back(5);
    items.push_back(8);

    if(items.size() > 1)
    {
        std::copy(items.begin(), --items.end(),
                  std::ostream_iterator<int>(oss, ", "));
        oss << "and ";
    }
    // else do nothing

    oss << items.back();

    std::cout << oss.str();
}

Выход:

1, 1, 2, 3, 5, and 8

1 голос
/ 15 марта 2012

Для этого есть два простых решения.Во-первых, используйте цикл while:

auto itemListIt = itemList.begin();
while ( itemListIt != itemList.end() ) {
    list << *itemListIt;
    ++ itemListIt;
    if ( itemListIt != itemList.end() ) {
        list << ", ";
    }
}

Второе решение - слегка изменить логику: вместо добавления ", ", если есть еще что-то, добавьте префикс один, если выне первый элемент:

for ( auto itemListIt = itemList.begin(); itemListIt != itemList.end(); ++ itemListIt ) {
    if ( itemListIt != itemList.begin() ) {
        list << ", ";
    }
    list << *itemListIt;
}
0 голосов
/ 04 мая 2012

И если вы хотите сделать это с картой или другими итераторами, которые не могут осуществлять произвольный доступ, как предлагали другие, проверьте первый элемент:

std::stringstream query;
query << "select id from dueShipments where package in (";
for (auto it = packageList.begin(); it != packageList.end(); it++)
{
    if (it != packageList.begin()) query << ", ";
    query << it->second;
}
query << ")";
0 голосов
/ 15 марта 2012

Следующее будет работать с любым InputIterator вводом:

std::stringstream list;
auto it(std::begin(input)); //Or however you get the input
auto end(std::end(input));
bool first(true);
for (; it != end; ++it)
{
    if (!first) list << ", ";
    else first = false;
    list << *it;
}

Или без дополнительной переменной:

std::stringstream list;
auto it(std::begin(input)); //Or however you get the input
auto end(std::end(input));
if (it != end)
{
    list << *it;
    ++it;
}
for (; it != end; ++it)
{
    list << ", " << *it;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...