mrange / cpplinq

LINQ for C++ (cpplinq) is an extensible C++11 library of higher-order functions for range manipulation. cpplinq draws inspiration from LINQ for C#.
http://cpplinq.codeplex.com/
Other
183 stars 40 forks source link

Iterating results without to_vector() #8

Open malamanteau opened 7 years ago

malamanteau commented 7 years ago

I was wondering, how can I iterate over query results without putting them into a vector first?

So for example, if I do this:

for (auto const & item : (cpplinq::from(ins) >> cpplinq::distinct() >> cpplinq::to_vector()))
{
    //stuff
}

I would rather iterate over each item in-place, without making a copy, is there a way to do this?

mwpowellhtx commented 7 years ago

@vectorantics I'm pretty sure from() and distinct() are both just cpplinq constructs, so, yes, AFAIK, you need to vector-ize it.

Stannieman commented 7 years ago

You can do something like:

GeneralResult generalResult;
cpplinq::from(calculators_)
    >> cpplinq::orderby([](const IResultCalculator &x) {return x.Priority; })
    >> cpplinq::for_each([&](IResultCalculator &x)
{
    x.CalculateResult(data, generalResult);
});

This function in the for_each will work on references to the original objects instead of copies. But then a question from my side: Is there a way to conditionally break out of this loop like the break keyword for normal loops? This solution is not very elegant:

GeneralResult generalResult;
bool brk = false;
cpplinq::from(calculators_)
    >> cpplinq::orderby([](const IResultCalculator &x) {return x.Priority; })
    >> cpplinq::for_each([&](IResultCalculator &x)
{
    if (brk)
    {
        return;
    }
    x.CalculateResult(data, generalResult);
    if (something)
    {
        brk = true;
    }
});
KN4CK3R commented 7 years ago

The preferred way would be for (auto&& x : ... >> experimental::container())