Question

What is an efficient way to erase the first element in a vector that matches a predicate? I am storing unique values in a vector so I wouldn't want the algorithm to search the whole container.

Currently I am doing:

if ((auto it = std::find_if(container.begin(),container.end(),
    [](Type& elem){ return elem == value;}) != container.end()))
{
        container.erase(it);
}

Thanks, in advance.

Was it helpful?

Solution

Only a minor improvement:

container.erase(
  std::remove(container.begin(), container.end(), value),
  container.end()
);

of if you want to use an unary predicate my_predicate:

container.erase(
  std::remove_if(container.begin(), container.end(), my_predicate),
  container.end()
);

This has exactly the same performance characteristics (find+erase together will touch all elements as well), but elegantly avoids special cases (!= container.end()) because it is ranged based.

If you don't care about keeping the vector stable (or sorted!) you can also swap the found element to the back() and pop_back() which will slightly improve the average (but not asymptotic!) runtime.

Not to forget this is also a commonly accepted C++ idiom, so it can be more easily recognized.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top