如何使用 C 避免其中带有“if”条件的“for”循环?

新手上路,请多包涵

对于我编写的几乎所有代码,我经常处理集合上的集合减少问题,这些问题最终会在它们内部出现天真的“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));

诚然,我正在做很多范式混合和基于主观/意见的风格,但我不禁觉得我错过了一些真正基础的东西,这些东西可以让我在 C++ 中使用这种首选技术。有人可以启发我吗?

原文由 Darkenor 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 385
2 个回答

恕我直言,使用带有 if 的 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; });

现场演示

原文由 101010 发布,翻译遵循 CC BY-SA 3.0 许可协议

Boost 提供了可用于基于范围的范围。范围的优点是它们不复制基础数据结构,它们仅提供“视图”(即 begin()end() 用于范围和 operator++() , operator==() 用于迭代器)。这可能是您感兴趣的:http: //www.boost.org/libs/range/doc/html/range/reference/adaptors/reference/filtered.html

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

原文由 lorro 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题