How to remove an element from std :: vector if the element identifier matches the search parameter

I am trying to write an algorithm that will search and remove an element from an element vector if the element identifier matches an argument. See the sample code below:

struct item{
    item(int newID){id = newID;}
    bool operator==(const item& other){return id = other.id;}
    int id
};

std::vector<std::unique_ptr<item>> vec;

vec.push_back(std::unique_ptr<item>(new item(10));
vec.push_back(std::unique_ptr<item>(new item(15));
vec.push_back(std::unique_ptr<item>(new item(20));

therefore, using the code above, I want to be able to search for an element that stores the value 15 and remove it from the vector, deleting it.

How can I do it?

Admittedly, I probably need to use unique pointers as well, so please feel free to correct me if my syntax is incorrect.

Some of my attempts:

void remove_item(int id){
    vec.erase(
               std::remove_if(
                               vec.begin(),
                               vec.end(),
                               [](const item& e){
                                     return id==e.id;
                               }),
               vec.end()
              );

An error occurs in the above code indicating that the variable identifier is not part of the capture list for the lambda expression.

Secondly, I tried:

void remove_item(item e){
    auto iter = std::find(vec.begin(), vec.end(), e);
    vec.erase(iter);
}

- ==.

+4
4

id , . , , *vec.begin(), std::unique_ptr<item>, item

void remove_item(int id){
    vec.erase(
               std::remove_if(
                               vec.begin(),
                               vec.end(),
                               [id](const std::unique_ptr<item>& e){
                                     return id==e->id;
                               }),
               vec.end()
              );
}

, - :

struct item {
    item(int newID) { id = newID; }
    bool operator==(const item& other) { return id == other.id; } // == here not =                                          
    int id;
};

std::vector<std::unique_ptr<item>> vec;

void remove_item(int id) {
    vec.erase(std::remove_if(
        vec.begin(), vec.end(), [id](const std::unique_ptr<item>& e) 
                                    {   return id == e->id; })
        ,vec.end());
}

int main()
{
    vec.push_back(std::unique_ptr<item>(new item(10))); // was missing a close paren
    vec.push_back(std::unique_ptr<item>(new item(15))); // was missing a close paren
    vec.push_back(std::unique_ptr<item>(new item(20))); // was missing a close paren
    remove_item(15);
    for (const auto & e : vec)
        std::cout << e->id << " ";
}

+3

id-erase-erase:

// search for this value
const int val = 15;

// use lambda capture to get "val" into lambda
auto lambda = [val] (const std::unique_ptr<item> & a) { return a->id == val;};

// use remove-erase idiom
auto rem = std::remove_if(vec.begin(), vec.end(), lambda);
vec.erase(rem, vec.end());
+2

, "erase remove_if". :

std::vector<std::unique_ptr<item>> vec;
vec.push_back(std::make_unique<item>(10));
vec.push_back(std::make_unique<item>(15));
vec.push_back(std::make_unique<item>(20));
vec.erase(std::remove_if(vec.begin(), vec.end(),
  [](std::unique_ptr<item> const& item) -> bool { return item->id > 10; }), vec.end());
std::cout << vec.size(); // Output will be 1
0

, , push_back insert emplace_back emplace C++ containers. , , : -

vector<unique_ptr<item>> v;
v.push_back(unique_ptr<item>(new item(5));

: -

vector<unique_ptr<item>> v;
v.emplace_back(new item(5));

-, , " " " " 15. , find_if, remove_if. remove_if ( find_if ), , remove_if , . find_if , . , .

Codes are as follows: -

// find_if
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
using namespace std;

struct item
{
    int x;
    item(){}
    item(int x)
    {
        this->x=x;
    }
};

int main()
{
    vector<unique_ptr<item>> v;
    v.emplace_back(new item(15));
    v.emplace_back(new item(5));
    v.emplace_back(new item(7));
    v.emplace_back(new item(15));
    v.emplace_back(new item(27));
    v.emplace_back(new item(15));
    v.emplace_back(new item(80));

    cout<<"deleting the item storing value 15...\n";
    auto itr = find_if(v.begin(), v.end(), [](unique_ptr<item> &u)     // you cant copy two `unique_ptr` as they can always be `moved & not copied`, hence we are `passing them by reference`
    {
        return (u->x==15);
    });
    v.erase(itr);    // as you need to remove only one item so specify the `iterator` pointing to the required item in `erase`

    for (auto &u:v)  see the use of `reference` again as without it the compiler throws error messages
    {
        cout<<u->x<<" ";
    }
    return 0;
}

The output will be: -

deleting the item storing value 15...
5 7 15 27 15 80

For remove_ifyou, you just need the following changes: -

auto itr = remove_if(v.begin(), v.end(), [](unique_ptr<item> &u)
    {
        return (u->x==15);
    });
    v.erase(itr,v.end());    // as you need to delete a range of items so you need to specify a range (here `itr` to `v.end()`) in `erase`

Here the output will be: -

deleting the items storing value 15...
5 7 27 80

Now I think your doubts would be properly cleared !!!

0
source

Source: https://habr.com/ru/post/1611475/


All Articles