如何避免使用C++在循环中包含“if”条件的“for”循环?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

几乎我写的所有代码,我经常处理集合中的集合减少问题,这些问题最终会以它们内部的“if”条件结束。这里有一个简单的例子:

for(int i=0; i<myCollection.size(); i++)
{
     if (myCollection[i] == SOMETHING)
     {
           DoStuff();
     }
}

使用功能性语言,我可以通过将收集减少到另一个收集(轻松)来解决问题,然后对缩减集执行所有操作。在伪代码中:

newCollection <- myCollection where <x=true
map DoStuff newCollection

而在其他C变体中,比如C#,我可以用一个where子句来减少

foreach (var x in myCollection.Where(c=> c == SOMETHING)) 
{
   DoStuff();
}

或者更好(至少在我眼中)

myCollection.Where(c=>c == Something).ToList().ForEach(d=> DoStuff(d));
提问于
用户回答回答于

恕我直言,它是更直接和更易于使用for循环与如果它内部。但是,如果这对你很烦人,你可以使用for_each_if下面的一个:

template<typename Iter, typename Pred, typename Op> 
void for_each_if(Iter first, Iter last, Pred p, Op op) {
  while(first != last) {
    if (p(*first)) op(*first);
    ++first;
  }
}

用例:

std::vector<int> v {10, 2, 10, 3};
for_each_if(v.begin(), v.end(), [](int i){ return i > 5; }, [](int &i){ ++i; });
用户回答回答于

Boost提供可以使用w / range-based的范围。范围具有使得它们不复制的基础数据结构,它们只是提供一个“视图”的优点(即,begin()end()为的范围和operator++()operator==()对于迭代)。

#include <boost/range/adaptor/filtered.hpp>
#include <iostream>
#include <vector>

struct is_even
{
    bool operator()( int x ) const { return x % 2 == 0; }
};

int main(int argc, const char* argv[])
{
    using namespace boost::adaptors;

    std::vector<int> myCollection{1,2,3,4,5,6,7,8,9};

    for( int i: myCollection | filtered( is_even() ) )
    {
        std::cout << i;
    }
}

扫码关注云+社区