Sergio
Sergio

Reputation: 941

remove_if from vector of strings

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

Answers (1)

Ivaylo Valchev
Ivaylo Valchev

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

Related Questions