Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get those elements of a vector, where another vector has '1's at corresponding indices

I have a two vectors

std::vector<int>   markedToBeRead(7);   // contains: 1,1,0,0,1,0,1
std::vector<float> myVec(7);            // contains: 1,2,3,4,5,6,7

What is the best way, to get those elements from myVec, where the corresponding indices of markedToBeRead have the value 1.
Is this possible without the use of a for-loop, but with stl-methods?

std::vector<float> myResult;            // contains: 1,2,5,7

Thank you!

like image 564
Massoud Avatar asked Jan 26 '26 20:01

Massoud


2 Answers

Clearly a simple for-loop would be very much preferred here rather than any STL algorithm.

But just as a proof of a concept one might adopt stl::equals and a lambda from C++11 here:

std::equal(myVec.begin(), myVec.end(), markedToBeRead.begin(), [&](float item, int mark)->bool {
    if (mark)
        myResult.push_back(item);
    return true;
});

This works, but looks ugly.

like image 140
Gart Avatar answered Jan 28 '26 10:01

Gart


Here’s how I’d write an algorithm for this:

template <typename I, typename O, typename M>
void mask_copy(I begin, I end, O obegin, M mbegin) {
    for (; begin != end; ++begin, ++mbegin)
        if (*mbegin)
            *obegin++ = *begin;
}

Called like this:

int a[] = { 1, 2, 3, 4, 5, 6, 7, 8 , 9 };
bool m[] = { true, false, false, false, true, false, false, true, false };

std::vector<int> out;
mask_copy(begin(a), end(a), back_inserter(out), begin(m));

(Requires C++11 for std::begin and std::end.)

That said, a proper implementation in a library would probably use enable_if (or static_assert) to ensure that the iterator types used are compatible with its use, i.e. that I is an input iterator, O a compatible output iterator, and M an input iterator whose value_type is bool. Unfortunately, lacking concepts this leads to a veritable template ’splosion.

like image 45
Konrad Rudolph Avatar answered Jan 28 '26 11:01

Konrad Rudolph



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!