remove element from vector <struct>

Feb 23, 2023 at 2:43am
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 Feb 23, 2023 at 2:44am
Feb 23, 2023 at 3:27am
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.
Feb 23, 2023 at 8:29am
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 Feb 23, 2023 at 8:29am
Feb 23, 2023 at 9:29am
For details on operations available for vectors, see
https://en.cppreference.com/w/cpp/container/vector

Feb 23, 2023 at 11:45am
Thanks all , solved
Feb 23, 2023 at 11:56am
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 Feb 23, 2023 at 11:57am
Feb 23, 2023 at 4:27pm
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.