remove element from vector <struct>

Hell all ,
Please how can remove element from this vector [parr1 ]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <string>
#include <vector>

using std::cout; using std::endl;
using std::vector; using std::string;

struct Person{
    string name;
    string surname;
    int age;
};

int main(){
    vector<Person> parr1 = {{"John", "Cooper", 32},
                                {"Theo", "Parrot", 23},
                                {"Kim", "Colbert", 53}};



    int i=0;
    for (const auto &arr : parr1) {
       
        cout << i << endl;
      
        cout << "Name: " << arr.name << endl
             << "Surname: " << arr.surname << endl
             << "Age: " << arr.age << endl;
         i++;  
         
    }
    

    return 0;
}
Last edited on
look at the remove/erase approach:
https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Erase-Remove#Erase-Remove

you can also pop the front or back, so swap the offending element to the back and pop back will do for simple approach.
The erase-remove idiom that jonnin mention is useful when you want to remove all elements that are equal to some object (in which case you use std::remove) or that satisfy some condition (in which case you use std::remove_if).

Since you haven't defined a == operator for you struct you would have to use std::remove_if.

1
2
// Remove all persons with an age less than 30
parr1.erase(std::remove_if(parr1.begin(), parr1.end(), [](const Person& p){ return p.age < 30; }), parr1.end());


If you're using C++20 you don't need to use the erase-remove idiom. You can use std::erase/std::erase_if instead.

1
2
// Remove all persons with an age less than 30
std::erase_if(parr1, [](const Person& p){ return p.age < 30; });


To remove a single element you can pass an iterator to the erase member function.

1
2
// Remove the person at index 1
parr1.erase(parr1.begin() + 1);

Iterators work similar to pointers. parr1.begin() gives you an iterator to the first element and by adding an index (integer) we get an iterator that refers to the element at that index. You cannot pass the index directly to erase because it only accepts iterators.
Last edited on
For details on operations available for vectors, see
https://en.cppreference.com/w/cpp/container/vector

Thanks all , solved
Note that since C++17 you can have an initialiser in a range_for. Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <string>
#include <vector>

using std::cout;
using std::vector;
using std::string;

struct Person {
	string name;
	string surname;
	unsigned age {};
};

int main() {
	vector<Person> parr1 { {"John", "Cooper", 32},
							{"Theo", "Parrot", 23},
							{"Kim", "Colbert", 53} };

	for (size_t i {}; const auto& arr : parr1)
		cout << i++ << '\n'
			<< "Name: " << arr.name << '\n'
			<< "Surname: " << arr.surname << '\n'
			<< "Age: " << arr.age << "\n\n";
}

Last edited on
And should you ever need it C++20 makes it possible to reverse a range-based for loop:

https://www.fluentcpp.com/2020/02/11/reverse-for-loops-in-cpp/

Something that was achievable using a classic or iterator based for loop for quite some time.
Topic archived. No new replies allowed.