'Break and then continue in for loops

I've built a function that iterates through until it finds a value bigger than the value given to the function and then breaks.

std::vector<AggregatedQuoteType>::iterator OrderBook::find_price(PriceType price)
{
   std::vector<AggregatedQuoteType>::iterator i = v_BuyOrders.begin();
    for (; i != v_BuyOrders.end(); ++i)
        if(i->get_price() >= price)        
            break;
   return i;        
}

I would then like it to test against another function, and if that does not hold then continue where the for loop was broken. Is that possible?



Solution 1:[1]

Just perform the second check inside the if and break only if it succeeds as well. Oh and don't forget brackets, they make the code readable! :)

std::vector<AggregatedQuoteType>::iterator OrderBook::find_price(PriceType price)
{
    std::vector<AggregatedQuoteType>::iterator i = v_BuyOrders.begin();
    for (; i != v_BuyOrders.end(); ++i){
        if(i->get_price() >= price && second_check(i->get_price())){
                break;
            }
        }
    }
    return i;       
}

This way, it'll perform your search, do both checks on your element, and break accordingly. If the second check doesn't succeed, it won't break continue from where it was in the loop.

Solution 2:[2]

If you consider that your 'another function' return true in case of success, how about something like:

std::vector<AggregatedQuoteType>::iterator OrderBook::find_price(PriceType price)
{
    std::vector<AggregatedQuoteType>::iterator i = v_BuyOrders.begin();
    for (; i != v_BuyOrders.end(); ++i)
    {
        if(i->get_price() >= price && another_function(i))
            return i;
    }
    return v_BuyOrders.end();
}

Since i is out of the for-loop, you can do it like that too:

std::vector<AggregatedQuoteType>::iterator OrderBook::find_price(PriceType price)
{
    std::vector<AggregatedQuoteType>::iterator i = v_BuyOrders.begin();
    for (; i != v_BuyOrders.end(); ++i)
    {
        if(i->get_price() >= price && another_function(i))
            break;
    }
    return i;
}

Solution 3:[3]

The most literal way of translating your envisaging of the logic into code is this:

std::vector<AggregatedQuoteType>::iterator OrderBook::find_price(PriceType price)
{
    std::vector<AggregatedQuoteType>::iterator i = v_BuyOrders.begin();
    do
    {
        for (; i != v_BuyOrders.end(); ++i)
            if(i->get_price() >= price)        
                break;
        return i; // i.e. end()
    } while (!another_function(*i));
    return i;
}

It simplifies to:

std::vector<AggregatedQuoteType>::iterator OrderBook::find_price(PriceType price)
{
    std::vector<AggregatedQuoteType>::iterator i;
    for (i = v_BuyOrders.begin(); i != v_BuyOrders.end(); ++i)
        if(i->get_price() >= price && another_function(*i))
            break;
    return i;
}

Or, if you want to use Standard algorithms for a more declarative approach:

#include <algorithm>
...

std::vector<AggregatedQuoteType>::iterator OrderBook::find_price(PriceType price)
{
    return std::find_if(v_BuyOrders.begin(), v_BuyOrders.end(), 
                        [](const AggregatedQuoteType& x)
                        { return x.get_price() >= price && another_function(x); });
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 JBL
Solution 2
Solution 3