How can I detect the last iteration in a loop over

2019-02-11 11:48发布

I'm trying to figure out the best way to determine whether I'm in the last iteration of a loop over a map in order to do something like the following:

for (iter = someMap.begin(); iter != someMap.end(); ++iter) {
    bool last_iteration;
    // do something for all iterations
    if (!last_iteration) {
        // do something for all but the last iteration
    }
}

There seem to be several ways of doing this: random access iterators, the distance function, etc. What's the canonical method?

Edit: no random access iterators for maps!

14条回答
迷人小祖宗
2楼-- · 2019-02-11 12:07

Modified Mark Ransom's so it actually work as intended.

finalIter = someMap.end();
--finalIter;
if (iter != final_iter)
查看更多
闹够了就滚
3楼-- · 2019-02-11 12:07

Here's my optimized take:

iter = someMap.begin();

do {
    // Note that curr = iter++ may involve up to three copy operations
    curr = iter;

    // Do stuff with curr

    if (++iter == someMap.end()) {
        // Oh, this was the last iteration
        break;
    }

    // Do more stuff with curr

} while (true);
查看更多
老娘就宠你
4楼-- · 2019-02-11 12:10

Full program:

#include <iostream>
#include <list>

void process(int ii)
{
   std::cout << " " << ii;
}

int main(void)
{
   std::list<int> ll;

   ll.push_back(1);
   ll.push_back(2);
   ll.push_back(3);
   ll.push_back(4);
   ll.push_back(5);
   ll.push_back(6);

   std::list<int>::iterator iter = ll.begin();
   if (iter != ll.end())
   {
      std::list<int>::iterator lastIter = iter;
      ++ iter;
      while (iter != ll.end())
      {
         process(*lastIter);
         lastIter = iter;
         ++ iter;
      }
      // todo: think if you need to process *lastIter
      std::cout << " | last:";
      process(*lastIter);
   }

   std::cout << std::endl;

   return 0;
}

This program yields:

 1 2 3 4 5 | last: 6
查看更多
贪生不怕死
5楼-- · 2019-02-11 12:11

Surprised no one mentioned it yet, but of course boost has something ;)

Boost.Next (and the equivalent Boost.Prior)

Your example would look like:

for (iter = someMap.begin(); iter != someMap.end(); ++iter) {
    // do something for all iterations
    if (boost::next(iter) != someMap.end()) {
        // do something for all but the last iteration
    }
}
查看更多
▲ chillily
6楼-- · 2019-02-11 12:11

How about this, no one mentioning but...

for (iter = someMap.begin(); iter != someMap.end(); ++iter) {
    // do something for all iterations
    if (iter != --someMap.end()) {
        // do something for all but the last iteration
    }
}

this seems simple, mm...

查看更多
等我变得足够好
7楼-- · 2019-02-11 12:12

If you just want to use a ForwardIterator, this should work:

for ( i = c.begin(); i != c.end(); ) {
        iterator cur = i++;
        // do something, using cur
        if ( i != c.end() ) {
                // do something using cur for all but the last iteration
        }
}
查看更多
登录 后发表回答