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!
Canonical? I can't claim that, but I'd suggest
final_iter = someMap.end();
--final_iter;
if (iter != final_iter) ...
Edited to correct as suggested by KTC. (Thanks! Sometimes you go too quick and mess up on the simplest things...)
Since C++11, you can also use std::next()
for (auto iter = someMap.begin(); iter != someMap.end(); ++iter) {
// do something for all iterations
if (std::next(iter) != someMap.end()) {
// do something for all but the last iteration
}
}
Although the question was asked a while ago, I thought it would be worth sharing.
This seems like the simplest:
bool last_iteration = iter == (--someMap.end());
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
}
}
Modified Mark Ransom's so it actually work as intended.
finalIter = someMap.end();
--finalIter;
if (iter != final_iter)
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
}
}
The following code would be optimized by a compiler so that to be the best solution for this task by performance as well as by OOP rules:
if (&*it == &*someMap.rbegin()) {
//the last iteration
}
This is the best code by OOP rules because std::map has got a special member function rbegin for the code like:
final_iter = someMap.end();
--final_iter;
Why to work to find the EOF so that you dont give something to it.
Simply, exclude it;
for (iter = someMap.begin(); someMap.end() - 1; ++iter) {
//apply to all from begin to second last element
}
KISS (KEEP IT SIMPLY SIMPLE)
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <algorithm>
using namespace boost::lambda;
// call the function foo on each element but the last...
if( !someMap.empty() )
{
std::for_each( someMap.begin(), --someMap.end(), bind( &Foo, _1 ) );
}
Using std::for_each will ensure that the loop is tight and accurate... Note the introduction of the function foo() which takes a single argument (the type should match what is contained in someMap). This approach has the added addition of being 1 line. Of course, if Foo is really small, you can use a lambda function and get rid of the call to &Foo.
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...
For someone who likes C++11 range-based loop:
for (const auto& pair : someMap) {
if (&pair != &*someMap.rbegin()) ...
}
Notice only reference type works here, not auto pair
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With