C++ Erase vector element by value rather than by position?
How about std::remove()
instead:
#include <algorithm>
...
vec.erase(std::remove(vec.begin(), vec.end(), 8), vec.end());
This combination is also known as the erase-remove idiom.
Remove an element from a vector by value - C++
You could use the Erase-remove idiom for std::vector
Quote:
std::vector<int> v;
// fill it up somehow
v.erase(std::remove(v.begin(), v.end(), 99), v.end());
// really remove all elements with value 99
Or, if you're sure, that it is unique, just iterate through the vector and erase the found element. Something like:
for( std::vector<T>::iterator iter = v.begin(); iter != v.end(); ++iter )
{
if( *iter == VALUE )
{
v.erase( iter );
break;
}
}
remove element by position in a vector string in c++
[Note: With the assumption 1003;2021-03-09;False;0;0;1678721F
corresponding to a row inside std::vector<string>
]
std::remove : Removes from the vector either a single element (position) or a range of elements ([first, last)).
In case std::vector<string> plan
contains value False
then it is removed.
std::vector < std::string > plan =
{
"1003","2021-03-09","False","0;0","1678721F"
};
std::remove(plan.begin(),plan.end(),"False");
In your case you need to remove given sub-string from each row of the plan
. You need to iterate through all the rows to remove given value using std::string::erase.
std::vector < std::string > plan =
{
"1003;2021-03-09;False;0;0;1678721F",
"1005;2021-03-05;False;0;0;1592221D",
"1005;2021-03-06;False;0;0;1592221D",
"1003;2021-03-07;False;0;0;1592221D",
"1003;2021-03-08;False;0;0;1592221D",
"1004;2021-03-09;False;0;0;1592221D",
"1004;2021-03-10;False;0;0;1592221D",
"1001;2021-03-11;False;0;0;1592221D"};
for (auto & e:plan)
{
//As position of False;0;0; is at a fixed index, i.e: from index:16, 10 characters are removed
e.erase (16, 10);
}
To generalize, You can make use of std::String::find to find a sub-string and erase it.
void removeSubstrs(string& s, string p) {
string::size_type n = p.length();
for (string::size_type i = s.find(p);
i != string::npos;
i = s.find(p))
s.erase(i, n);
}
int
main ()
{
std::vector < std::string > plan =
{
"1003;2021-03-09;False;0;0;1678721F",
"1005;2021-03-05;False;0;0;1592221D",
"1005;2021-03-06;False;0;0;1592221D",
"1003;2021-03-07;False;0;0;1592221D",
"1003;2021-03-08;False;0;0;1592221D",
"1004;2021-03-09;False;0;0;1592221D",
"1004;2021-03-10;False;0;0;1592221D",
"1001;2021-03-11;False;0;0;1592221D"};
for (auto & e:plan)
{
removeSubstrs (e, ";False;0;0");
}
for (auto e:plan)
std::cout << e << std::endl;
return 0;
}
How do I erase an element from std::vector by index?
To delete a single element, you could do:
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
// Deletes the second element (vec[1])
vec.erase(std::next(vec.begin()));
Or, to delete more than one element at once:
// Deletes the second through third elements (vec[1], vec[2])
vec.erase(std::next(vec.begin(), 1), std::next(vec.begin(), 3));
How do I remove an item from a stl vector with a certain value?
std::remove
does not actually erase elements from the container: it moves the elements to be removed to the end of the container, and returns the new end iterator which can be passed to container_type::erase
to do the actual removal of the extra elements that are now at the end of the container:
std::vector<int> vec;
// .. put in some values ..
int int_to_remove = n;
vec.erase(std::remove(vec.begin(), vec.end(), int_to_remove), vec.end());
How to find a value to remove from a vector, and remove the same position from a secondary vector?
First of all, a vector called set1
or set2
is strange. Why not use std::set
?
Anyway, supposing that set2
is not smaller than set1
, a very generic solution would be to use std::distance
to calculate the distance between the find result and the start of set1
. You can then just add the distance to the start of set2
:
#include <vector>
#include <algorithm>
#include <iostream>
#include <string>
int main()
{
std::vector<int> set1 = { 4, 5, 2 };
std::vector<std::string> set2 = { "a", "b", "c" };
using std::begin;
using std::end;
// get iterator to first '5' element:
auto const set1_iter = std::find(begin(set1), end(set1), 5);
// how many steps does it take to go from start to the '5' element?
auto const distance = std::distance(begin(set1), set1_iter);
// go to same position in set2:
auto const set2_iter = begin(set2) + distance;
// use position to erase the element:
set2.erase(set2_iter);
for (auto&& element : set2)
{
std::cout << element << "\n";
}
}
In real code, you will want to add some error handling for the case when set2
is smaller or when 5 does not exist.
std::vector removing elements which fulfill some conditions
std::remove_if
comes to the rescue!
99 would be replaced by UnaryPredicate
that would filter your delays, which I am going to use a lambda function for.
And here's the example:
v.erase(std::remove_if(
v.begin(), v.end(),
[](const int& x) {
return x > 10; // put your condition here
}), v.end());
vector erase specific indexes with iterators (not based on range or condition)
Your problem is very simple:
std::vector<int> index_to_filter{ 1, 5, 8 };
You intent is to remove elements #1, #5, and #8 from the other array, and you start with element #1:
Value 0 1 2 3 4 5 6 7 8 9
Index 0 1 2 3 4 5 6 7 8 9
^ ^ ^
The bottom line, the "index" line, is the index into the vector. The top line, the "value" line, is the value in that position in the vector. When you start, the two values are the same.
The carets mark the indexes you wish to remove, and you start with element #1.
The fundamental gap that you are ignoring is that when you remove an element from the vector, you do not exactly have a gaping black hole, a void in that position. All subsequent values in the container shift over. So, when you remove element #1, the remaining values shift over:
Value 0 2 3 4 5 6 7 8 9
Index 0 1 2 3 4 5 6 7 8
^ ^
The next element you wish to remove is element #5. Unfortunately, the value at that position in the vector is no longer 5. It is 6, because the array has shifted. Your code than proceeds and removes index position #5, which has the following result:
Value 0 2 3 4 5 7 8 9
Index 0 1 2 3 4 5 6 7
^
You have already gone off the rails here. But now, your code attempts to remove index #8, which no longer exists, since the vector is now shorter. As soon as your code attempts to do that, you blow up.
So, in conclusion: what you're missing is the simple fact that removing a value from a middle of a vector shifts all subsequent values up by one position, in order to fill the gap left from the removed element, and the code you wrote fails to account for that.
The simplest solution is to remove elements from the highest index position to the lowest. In your code, you already have index_to_filter
in sorted order, so instead of iterating from the beginning of index_to_filter
to its end, from the lowest to the highest index, iterate backwards, from the last index in index_to_filter
to the first, so your code attempts to remove indexes 8, 5, then 1, so that each time the removal of the element does not affect the lower index positions.
How to remove element from vector by value but only single instance of that value?
You may use:
v.erase(v.begin() + std::max(index1, index2));
v.erase(v.begin() + std::min(index1, index2));
or even
auto indexes = std::minmax(index1, index2);
v.erase(v.begin() + indexes.second);
v.erase(v.begin() + indexes.first);
C++ Remove element from vector by value
std::remove
is only available if you include header <algorithm>
.
This is clearly stated by the MSDN documentation here as well as any C++ reference.
Related Topics
How to Easily Format My Data Table in C++
How to Get Console Output in C++ With a Windows Program
Heterogeneous Containers in C++
How to Know the Exact Line of Code Where an Exception Has Been Caused
Functions With Const Arguments and Overloading
Rand() % 14 Only Generates the Values 6 or 13
Non-Blocking Worker - Interrupt File Copy
When Passing an Array to a Function in C++, Why Won't Sizeof() Work the Same as in the Main Function
What Techniques Can Be Used to Speed Up C++ Compilation Times
How Many and Which Are the Uses of "Const" in C++
Compelling Examples of Custom C++ Allocators
Smart Pointers: Who Owns the Object
How Does the Ampersand(&) Sign Work in C++
How to Search/Find and Replace in a Standard String
Direct Way of Computing Clockwise Angle Between 2 Vectors
How to Enable Gdb Pretty Printing For C++ Stl Objects in Eclipse Cdt