Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert into vector with conditional iterator

Tags:

c++

iterator

Say I have a vector with various entries, which I want to insert into another vector, while leaving out entries that satisfy a condition.

For example, I want to insert a vector while leaving out all three's.

{1, 3, 2, 3, 4, 5, 3} -> { /* previous content, */ 1, 2, 4, 5}

What I came up with so far uses std::partition, which does not preserve the relative order and rearranges the source vector.

std::vector<int> source({1, 3, 2, 3, 4, 5, 3});
std::vector<int> target;

auto partition = std::partition(std::begin(source),
                   std::end(source), [](const auto& a) { return a == 3; });
target.insert(std::begin(target), partition, std::end(source));

What I am looking for is more of an iterator that checks a condition and moves on if the condition is not satisfied. Something like this:

target.insert(std::begin(target),
              conditional_begin(source, [](const auto& a) { return a != 3; }),
              conditional_end(source));

I suppose a conditional_end function would be necessary, since std::end would return a different iterator type than conditional_begin.

Maybe I have overlooked something, so my questions are:

  • Does the standard library provide something similar?
  • Is there a different easy way to achieve my goal?
  • Is there an easy way to implement the conditional iterator functionality?
like image 712
KorbenDose Avatar asked Jul 30 '18 13:07

KorbenDose


People also ask

What happens to iterator after insert?

During insertion vector is allowed to move body of the vector to some other place. If vector will move the body, your iterator end will continue pointing to the same place.

How do you add something to a vector in C++?

The C++ function std::vector::insert() extends vector by inserting new element at position in container. Reallocation happens if there is need of more space. This function increases container size by one.

Can we push front in vector?

Adding to the front of a vector means moving all the other elements back. If you want (to constantly perform) front insertion, you might really want to use list or deque . The only way to know how to speed up your program is with profiling.


1 Answers

Is there a different easy way to achieve my goal?

Yes, the standard already has this functionality built in. The function you are looking for is std::copy_if.

std::vector<int> source({1, 3, 2, 3, 4, 5, 3});
std::vector<int> target;

std::copy_if(source.begin(), 
             source.end(), 
             std::back_inserter(target), [](auto val){ return val != 3; });

Here, std::back_inserter(target), will call push_back on target for each element that the predicate returns true.

like image 182
NathanOliver Avatar answered Oct 05 '22 20:10

NathanOliver