Reputation: 1291
std::vector<int> items = {1, 2, 3, 4, 5};
std::vector<int> removeItems = {2, 4};
I need to delete the values in items
that are in removeItems
, while retaining the order of items
. Something like this:
items.remove(removeItems);
Output
items = {1, 3, 5}
Are there any built in vector methods that can achieve this? I haven't found any that accept another vector of items to remove. If not, whats the most efficient way of achieving this?
Edit
Erasing elements from a vector This post refers to removing one item at a time, I'm looking to delete a whole bunch at once in a more compact way then
for(num in removeItems) {
items.erase(std::remove(items.begin(), items.end(), num), items.end())
}
Because surely this way of removing items is very inefficient because you have to check the entire items
vector twice (removeItems.size()
) for each item in removeItems
Edit 2
Number of elements in items
or removeItems
will be in the range 0-10000
Upvotes: 0
Views: 975
Reputation: 172924
You can apply erase-remove idiom, with help of std::remove_if
and std::find
.
std::vector<int> items = {1, 2, 3, 4, 5};
std::vector<int> removeItems = {2, 4};
items.erase(std::remove_if(std::begin(items),
std::end(items),
[&removeItems](auto i) { return std::find(std::begin(removeItems), std::end(removeItems), i) != std::end(removeItems); }),
std::end(items));
Note that std::remove_if
just shifts the elements to be removed to the back of the vector
; these elements are erased by std::vector::erase
later at a time.
Upvotes: 2
Reputation: 117681
The most efficient general form is to turn removeItems
into an unordered set, and then remove elements from items
by checking for membership.
std::unordered_set<int> removeSet(removeItems.begin(), removeItems.end());
items.erase(std::remove_if(items.begin(), items.end(), [&](int x) {
return removeSet.count(x) != 0;
}), items.end());
If removeItems
is small a linear scan is probably faster than turning it into an unordered set. For large removeItems
the above is the most efficient, unless it has a very special form (such as only having small elements).
If both arrays are already sorted (like they are in your example, assuming that isn't coincidence) you can do even better than the above.
Upvotes: 2