std::remove but specify max elements to remove?

std::remove will 'remove' every matching element in a container, how can I specify that it removes up to a max number of matching elements?
There's no way to get std::remove to do that, but you can do it using std::remove_if:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    const int MaxRemove = 3;

    std::vector<int> v{ 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1 };
    for ( int n: v ) std::cout << n << ' '; std::cout << '\n';
    std::cout << std::count( v.begin(), v.end(), 1 ) << " 1's\n";

    int n = 0;
    v.erase( std::remove_if( v.begin(), v.end(),
                             [&](auto x){ return x == 1 && n++ < MaxRemove; } ),
             v.end() );

    for ( int n: v ) std::cout << n << ' '; std::cout << '\n';
    std::cout << std::count( v.begin(), v.end(), 1 ) << " 1's\n";
}

can you do a remove-if with some sort of counter?
you may also be able to tamper with the iterator from remove so that when you call erase it only picks up to N?
Last edited on
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 <vector>
#include <algorithm>
using namespace std;

template<typename T>
void removeSome( vector<T> &V, T value, int n, int i = 0 )
{
   if ( n <= 0 || i >= V.size() ) return;
   auto it = find( V.begin() + i, V.end(), value );
   if ( it == V.end() ) return;
   i = it - V.begin();
   rotate( it, it + 1, V.end() );
   V.pop_back();
   removeSome( V, value, n - 1, i );
}


template<typename T>
ostream & operator << ( ostream &out, const vector<T> &V )
{
   for ( T e : V ) out << e << ' ';
   return out;
}


int main()
{
    const int MaxRemove = 3, Value = 1;
    vector<int> V{ 2, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1 };

    cout << "Before: " << V << '\n';
    removeSome( V, Value, MaxRemove );
    cout << "After: " << V << '\n';
}
Topic archived. No new replies allowed.