Reputation: 941
I need to remove some elements from a vector of strings if any of the strings contain a certain word.
How can I write the unary predicate for remove_if
?
Here is code sample:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
bool remove_if_found(string word)
{
// ???
}
int main()
{
vector<string> data {
{ "the guitar has six strings" },
{ "the violin has four strings" },
{ "the the violin is more difficult to learn" },
{ "saxophones are a family of instruments" },
{ "the drum is a set of percussions" },
{ "the trumpet is a brass" }
};
cout << data.size() << endl; // output: 6
remove_if(data.begin(), data.end(), remove_if_found("violin")); // error
cout << data.size() << endl; // output should be: 4
return 0;
}
Upvotes: 3
Views: 1363
Reputation: 10425
The problem is that the expression remove_if_found("violin")
returns a bool
which cannot be passed to std::remove_if
.
The easiest solution for you would be to change remove_if_found
as such:
void remove_if_found(vector<string>& vec, const string& word)
{
vec.erase(remove_if(vec.begin(), vec.end(), [&word](const string& el) {
// check if the word is contained within the string
return el.find(word) != std::string::npos;
}), vec.end());
}
which takes a reference to the vector as well as the string to look for and does the removal as normal.
Then in main
you just call it as such:
remove_if_found(data, "violin");
The reason for the erase+remove usage in the remove_if_function
is important. std::remove_if
merely moves the elements you wish to remove to the end of the vector and returns an iterator to the first of those (re)moved elements. On the other hand std::vector::erase
takes two iterators - the returned one from std::remove_if
iterator and vec.end()
and actually erases them from the vector.
Upvotes: 6