WEBVTT

00:00:00.540 --> 00:00:05.040
We now know how to push objects at the specific position in the array, but

00:00:05.050 --> 00:00:09.880
there is also a way to remove them. Erase function will delete the element

00:00:09.890 --> 00:00:15.200
at the specific index, but we also have to provide this position by using

00:00:15.200 --> 00:00:20.450
the begin iterator. I want to erase the first element, so I will just pass

00:00:20.450 --> 00:00:22.060
the iterator itself.

00:00:22.940 --> 00:00:24.160
Let's compile this.

00:00:25.440 --> 00:00:29.440
The first element had an ID of 1, and it seems that it was

00:00:29.440 --> 00:00:31.650
successfully removed from the array.

00:00:32.540 --> 00:00:36.630
Move assignment operator was invoked four times because these four

00:00:36.630 --> 00:00:40.500
subjects have to be moved to the start of the array to fill in the

00:00:40.500 --> 00:00:42.950
blank left by the erased element.

00:00:43.840 --> 00:00:46.800
But we can also remove a range of elements by providing

00:00:46.800 --> 00:00:49.260
the starting and ending position.

00:00:49.740 --> 00:00:54.980
I want to start at the index of 1 and stop at the index of 3. Erase

00:00:54.980 --> 00:00:58.920
function will remove the element at the starting index, but it will

00:00:58.920 --> 00:01:01.950
not remove the element at the ending index.

00:01:03.240 --> 00:01:04.459
Let's compile this.

00:01:05.940 --> 00:01:10.380
As you can see, only the second and third element were removed from the vector

00:01:10.390 --> 00:01:15.690
because the starting index was 1. Index 3, which defines the end of the

00:01:15.690 --> 00:01:19.960
specified range, is not included in this deletion process.

00:01:20.340 --> 00:01:24.080
You can see that the move assignment was invoked two times.

00:01:24.090 --> 00:01:27.900
This is because vector moved these last two elements and

00:01:27.900 --> 00:01:30.450
placed them on top of the deleted ones.

00:01:31.740 --> 00:01:35.970
Now we have a way of removing elements at the specific position, but what

00:01:35.970 --> 00:01:40.460
if we want to do something more challenging? For example, let's say that I

00:01:40.460 --> 00:01:45.590
have this vector of integers, and I want to get rid of all of the 6s. We

00:01:45.590 --> 00:01:49.530
could create a for loop, which will go over all of the elements, and when

00:01:49.530 --> 00:01:54.370
it finds a 6 at the specific index, it will pass that position to the

00:01:54.380 --> 00:01:55.450
erase function.

00:01:55.840 --> 00:01:58.030
But there is a better way to do this.

00:01:58.040 --> 00:02:01.660
We can use the remove function from the algorithm library.

00:02:03.340 --> 00:02:05.950
The first two arguments specify the range,

00:02:05.960 --> 00:02:10.449
a part of the vector that we want this remove function to operate on.

00:02:11.140 --> 00:02:14.430
Usually, we want to do this on the whole vector, so we can

00:02:14.430 --> 00:02:16.960
pass the begin and the end iterator.

00:02:17.640 --> 00:02:22.650
The third argument is the value that we want to remove, in this case 6.

00:02:23.540 --> 00:02:27.620
The remove function doesn't actually move anything. It just moves the wanted

00:02:27.620 --> 00:02:32.800
elements over the unwanted ones, but the leftovers are still there in the

00:02:32.800 --> 00:02:36.160
vector. The size of the vector will not change.

00:02:36.940 --> 00:02:38.350
Let me show you what I mean.

00:02:39.040 --> 00:02:43.540
So this is how the vector looks like at the beginning. Remove

00:02:43.540 --> 00:02:46.820
function will start to look through the elements and check

00:02:46.820 --> 00:02:49.050
which one of them are unwanted.

00:02:49.440 --> 00:02:54.660
The first element is 2. It is not 6, so this one is wanted,

00:02:55.740 --> 00:02:57.460
The second element is 7.

00:02:57.470 --> 00:03:01.870
This one is also not 6, so nothing has to move. We want all of

00:03:01.870 --> 00:03:04.760
the unwanted elements at the end of the array.

00:03:05.440 --> 00:03:09.810
Now we get to the third element, which is 6. And as we know, 6 is

00:03:09.820 --> 00:03:15.640
unwanted. But this is still okay because the unwanted number is at the

00:03:15.640 --> 00:03:18.050
end of this part of the array we covered.

00:03:18.440 --> 00:03:21.650
However, once we get to the number 8, which is wanted,

00:03:21.660 --> 00:03:25.160
the unwanted number 6 is no longer at the end.

00:03:25.540 --> 00:03:29.380
So the remove function will move this number 8 over to

00:03:29.380 --> 00:03:33.410
number 6. Move might not be the right word.

00:03:33.420 --> 00:03:37.760
If this was an object with move semantics, it would indeed move it.

00:03:37.770 --> 00:03:40.770
But since these are just primitive integers,

00:03:40.780 --> 00:03:44.960
it will actually copy the value 8 over this integer 6.

00:03:45.740 --> 00:03:50.220
This other element with the integer of 8 is also unwanted because

00:03:50.220 --> 00:03:53.210
this is just the leftover from the rearrangement.

00:03:53.220 --> 00:03:57.950
So the function will treat this number just as the unwanted number 6.

00:03:58.340 --> 00:04:01.060
The next element is 1, which is wanted.

00:04:01.740 --> 00:04:04.920
Since this 8 is a leftover and unwanted,

00:04:04.930 --> 00:04:08.280
we need to copy this wanted number 1 over it because

00:04:08.290 --> 00:04:11.160
unwanted numbers always have to be at the end.

00:04:12.440 --> 00:04:14.960
The next element is the unwanted 6.

00:04:14.960 --> 00:04:19.360
And since this 1 is also unwanted, we don't do anything.

00:04:19.370 --> 00:04:22.360
All of the unwanted elements are at the end.

00:04:22.740 --> 00:04:23.230
Finally,

00:04:23.230 --> 00:04:27.340
this number 5 is wanted, so we can make a copy of it and

00:04:27.340 --> 00:04:30.260
put it over the last unwanted number.

00:04:31.240 --> 00:04:34.500
And this is how the final vector looks like. If you

00:04:34.500 --> 00:04:36.080
ignore these last two elements,

00:04:36.080 --> 00:04:39.410
you can see that all of the wanted numbers from the original array are

00:04:39.410 --> 00:04:45.970
correctly placed, and all of the 6s are removed. But these leftovers are

00:04:45.970 --> 00:04:51.640
still here at the end, and we don't need them. Fortunately, the remove

00:04:51.640 --> 00:04:55.700
function will return the iterator that points to the start of the unwanted

00:04:55.700 --> 00:05:01.170
part of the array, in this case, the position of this number 6. We can use

00:05:01.170 --> 00:05:05.970
this return value to pass this function as a first argument of the erase

00:05:05.970 --> 00:05:06.550
range.

00:05:07.740 --> 00:05:10.440
The ending iterator will be the end of the array.

00:05:10.450 --> 00:05:14.720
So, in other words, these unwanted leftovers will be deleted

00:05:14.720 --> 00:05:17.460
from the vector by the erase function.

00:05:18.340 --> 00:05:22.180
This combination of remove and erase function is so common that

00:05:22.180 --> 00:05:25.060
we call this technique erase‑remove idiom.

00:05:25.740 --> 00:05:30.030
You use this idiom whenever you want to eliminate elements that fulfill a

00:05:30.030 --> 00:05:36.560
certain criteria, in this case, the number 6. Since this idiom is so common,

00:05:36.570 --> 00:05:42.930
C++ 20 provides us with another function named erase, but don't confuse this

00:05:42.930 --> 00:05:45.960
erase function with the vector's erase function.

00:05:46.340 --> 00:05:49.840
The erase function we used belongs to the vector class while

00:05:49.840 --> 00:05:53.470
this new function belongs to the global scope, and it is

00:05:53.470 --> 00:05:56.060
defined inside of the vector header.

00:05:57.140 --> 00:06:00.030
This new function is combining the vector's erase

00:06:00.030 --> 00:06:02.290
function and the remove function.

00:06:02.300 --> 00:06:06.350
It basically implements the erase‑remove idiom on its own.

00:06:06.840 --> 00:06:10.660
All we need to provide is the whole vector and then the value we

00:06:10.660 --> 00:06:14.910
want to remove from that vector. Erase function will assume that we

00:06:14.910 --> 00:06:18.360
want to work with the whole array, and it will first reorganize the

00:06:18.360 --> 00:06:22.450
vector like the remove function and then erase the leftovers like

00:06:22.450 --> 00:06:24.160
the old erase function.

00:06:24.540 --> 00:06:27.760
This is so much easier than using two functions and

00:06:27.760 --> 00:06:30.260
passing iterators all over the place.

00:06:31.240 --> 00:06:33.370
Now that we know how these functions work, let's

00:06:33.370 --> 00:06:35.260
use them on the subject's vector.

00:06:35.640 --> 00:06:38.410
I want to work on the whole vectors, so I will pass

00:06:38.410 --> 00:06:40.860
both iterators to the remove function.

00:06:41.240 --> 00:06:45.520
The third argument is a value, but this is a little bit more complicated

00:06:45.520 --> 00:06:49.360
because subjects are not a primitive data types like integers.

00:06:49.740 --> 00:06:53.400
Fortunately, there is a complimentary remove_if function, which

00:06:53.400 --> 00:06:55.750
does the same thing as the remove function.

00:06:55.760 --> 00:06:58.580
But instead of passing the value you want to remove,

00:06:58.590 --> 00:07:01.260
you pass a function that returns a boolean.

00:07:01.640 --> 00:07:05.150
This function will be a lambda because we only need it here.

00:07:06.040 --> 00:07:09.060
Every element from this vector will be passed down to this

00:07:09.060 --> 00:07:12.290
function, so I will make sure that I pass it by reference

00:07:12.290 --> 00:07:14.460
to avoid unnecessary copies.

00:07:15.340 --> 00:07:18.560
I want to remove all of the subjects with the ID of 2.

00:07:18.860 --> 00:07:23.460
So if a subject has the ID of 2, I will return true.

00:07:24.240 --> 00:07:27.480
This is the list of IDs before the remove_if function.

00:07:27.490 --> 00:07:31.550
Can you try to guess what this vector will look like after we execute the

00:07:31.550 --> 00:07:35.910
function? Following the same logic from the previous example, we know that the

00:07:35.910 --> 00:07:39.480
first element is wanted because it has an ID of 1.

00:07:39.730 --> 00:07:41.780
The next element is unwanted.

00:07:41.790 --> 00:07:47.020
But since it's at the end, we don't care. However, 3 is wanted, so we need

00:07:47.020 --> 00:07:51.590
to call the move assignment operator to move the subject 3 over to subject

00:07:51.590 --> 00:07:56.040
2. Since moving invalidates old subjects,

00:07:56.050 --> 00:08:01.750
this element is left with an empty object with the ID of 0. ID 2

00:08:01.750 --> 00:08:05.160
is unwanted, so we move on to the last element.

00:08:06.240 --> 00:08:11.030
Since unwanted elements have to be at the end, we move assign these four over

00:08:11.030 --> 00:08:16.080
the empty subject because that is the first unwanted subject in the array.

00:08:16.080 --> 00:08:19.880
This invalidates the object at the last position.

00:08:19.890 --> 00:08:25.560
So the final ID list is 1, 3, 4, 2, and 0.

00:08:26.440 --> 00:08:32.260
I can prove this by compiling this program, and it all works as we expected.

00:08:32.270 --> 00:08:35.150
It only needs to do two move assignments to

00:08:35.150 --> 00:08:37.559
reorganize elements in the right way.

00:08:38.340 --> 00:08:42.210
Now we can pass the result of this function to the vector's erase function.

00:08:42.220 --> 00:08:47.540
But instead of doing that, let's remove this and use the new erase function.

00:08:47.550 --> 00:08:52.050
I just need to pass in the vector and the condition presented with lambda.

00:08:52.940 --> 00:08:57.260
When working with lambdas, we can use the complimentary erase_if function,

00:08:57.260 --> 00:09:01.360
which combines the vector's erase and the remove_if algorithm.

00:09:02.240 --> 00:09:05.460
And if I now compile this, you can see that the elements with

00:09:05.460 --> 00:09:08.750
the ID of 2 are also deleted from the vector.

00:09:09.640 --> 00:09:12.230
Okay, that is all I have to say on vectors.

00:09:12.240 --> 00:09:15.060
If you have any questions, ask them in the discussion.
