5

I have a QVector

 QVector(48, 64,  31, -2, 14, 5, 7, -3, -1, 13) 

I want to know how to use Qt mechanism to remove all the elements that are smaller than 0.

How do I do this in a simple way?
Thanks

Theodore Tang
  • 831
  • 2
  • 21
  • 42

2 Answers2

9

QVector's interface allows it to be used with the std algorithms, so you can just use the erase-remove idiom

QVector<int> vec;
...
vec.erase(std::remove_if(vec.begin(), vec.end(), [](int i) { return i < 0; }), 
          vec.end());

By way of explanation:

remove_if takes a range of iterators (vec.begin(), vec.end()), and moves all elements for which the provided lambda returns true to the end. It then returns an iterator to the beginning of this range.

erase takes a range of iterators (the returned value from remove_if and vec.end()) and erases them from the vector.

Working example:

#include <QVector>
#include <iostream>

int main()
{
    QVector<int> vec { 1, 2, 3, -1, -2, -3, 4, 5, 6, -7, -8, -1, 1, 2, 3 };

    // erase all elements less than 0
    vec.erase(std::remove_if(vec.begin(), vec.end(), [](int i) { return i < 0; }),
              vec.end());

    // print results
    for (int i : vec)
        std::cout << i << ' ';
    std::cout << '\n';

    return 0;
}

Output:

./a.out  
1 2 3 4 5 6 1 2 3
Steve Lorimer
  • 27,059
  • 17
  • 118
  • 213
  • 1
    Exactly, when profiling both solutions Remi's solution takes about 2x time compared with this solution... – Mike Nov 21 '17 at 13:10
0
// Create your list
QVector<int> listIntegers;
... 

// Remove all numbers < 0 from QVector<int> 
QMutableVectorIterator<int> i(listIntegers);
while (i.hasNext()) {
    if (i.next() < 0)
        i.remove();
}

You can also adapt this piece of code to do what you want, just by changing the condition inside the while loop.

Rémi
  • 525
  • 1
  • 15
  • 26
  • 1
    JLev did not suggest using iterators. The question is a typical application of the [Erase-remove idiom](https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom) and this is what JLev suggested. I profiled both solutions, this solution takes about 2x the time requisite by the erase-remove idiom. As it might resize the container multiple times during the operation... – Mike Nov 21 '17 at 13:05
  • 1
    @SteveLorimer, No, it doesn't skip the first element of the array because Qt's Java-style iterators point "in-between" elements rather than at elements themselves, see [here](https://doc.qt.io/qt-5/containers.html#java-style-iterators) – Mike Nov 21 '17 at 13:08