如何检测在一个循环过的std ::地图最后一次迭代?(How can I detect the la

2019-07-20 14:38发布

我试图找出最好的方法来确定我是否在一个循环中在地图的最后一次迭代,以做类似如下:

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

似乎有这样做的几种方法:随机访问迭代器,在distance功能等什么是规范的方法?

编辑:对于地图没有随机访问迭代器!

Answer 1:

典范? 我不能说,但我会建议

final_iter = someMap.end();
--final_iter;
if (iter != final_iter) ...

编辑以纠正的建议KTC 。 (感谢!有时候,你去得迅速陷入困境的最简单的事情...)



Answer 2:

由于C ++ 11,你也可以使用std ::下一个()

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

虽然这个问题是前一阵子问,我认为这将是值得分享。



Answer 3:

这似乎是最简单的:

bool last_iteration = iter == (--someMap.end());


Answer 4:

如果你只是想使用ForwardIterator,这应该工作:

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


Answer 5:

修改马克赎金的所以它实际上像预期的那样。

finalIter = someMap.end();
--finalIter;
if (iter != final_iter)


Answer 6:

惊讶没有人提到过,但当然升压有事;)

Boost.Next (和等效Boost.Prior)

你的榜样将如下所示:

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


Answer 7:

下面的代码会被编译器优化,使得要通过性能以及由OOP规则,这个任务的最佳解决方案:

if (&*it == &*someMap.rbegin()) {
    //the last iteration
}

这是OOP规则最好的代码,因为的std ::地图已经得到了像代码中的特殊成员函数rbegin:

final_iter = someMap.end();
--final_iter;


Answer 8:

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

使用std :: for_each的将确保循环很紧,准确...注意引进函数foo(),它接受一个参数(类型应该匹配什么是包含在someMap)的。 这种方式的补充添加为1行。 当然,如果foo是非常小的,你可以使用lambda功能,摆脱通话到&美孚。



Answer 9:

为什么要工作,找到EOF,让你不给什么东西。

简单地说,它排除在外;

for (iter = someMap.begin(); someMap.end() - 1; ++iter) {
    //apply to all from begin to second last element
}

KISS(KEEP IT SIMPLE SIMPLY)



Answer 10:

一个简单而有效的方法:

  size_t items_remaining = someMap.size();

  for (iter = someMap.begin(); iter != someMap.end(); iter++) {
    bool last_iteration = items_remaining-- == 1;
  }


Answer 11:

这里是我的优化见解:

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


Answer 12:

这个怎么样,没有人提,但...

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

这看似简单,毫米...



Answer 13:

完整的程序:

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

这个程序产生:

 1 2 3 4 5 | last: 6


Answer 14:

你可以只拉一个元素了之前的地图进行迭代,然后执行你的“最后一次迭代”工作圈外的,然后把元素放回地图。 这是异步代码可怕的坏,但考虑到C ++的其余部分是多么糟糕的并发性,我不认为这会是一个问题。 :-)



文章来源: How can I detect the last iteration in a loop over std::map?