Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt: How to subtract two QSet of QString in case insensitivity mode

I'm working on a logical problem using Qt. I've got two QSets of QString:

QSet<QString> set1: [ "aaa", "BBB" ]
QSet<QString> set2: [ "aaa", "bbb", "ccc", "ddd" ]

I want to subtract set1 from set2, so I use:

set2.subtract( set1 );

And I obtain:

set2: ["bbb", "ccc", "ddd"]

But in that case "bbb" isn't removed from set2, although set1 contains this record. That's because the default QString::contains method (it is the method used by QSet::subtract) is case sensitive.

There is another QString::contains method which takes a parameter to define the case sensitivity mode, but I don't really see how I could use it.

Does anyone have an idea how to make a case insensitive subtraction between two QSet of QString, please?

Here's what I've tried so far:

Transform both sets in uppercase set2 is displayed in a list, so it won't be fancy if all items are in uppercase (or lowercase neither).

Extend QSet class and override subtract method I've tried to extend this class with a MyStringSet custom class, but I'm not very comfortable with Qt and this appears to me quite complicated.

like image 201
Gildas Avatar asked Dec 21 '22 14:12

Gildas


2 Answers

Qt container classes are largely compatible with STL. And std::set_difference allows specifying a comparator. This is very useful when you only need case insensitivity in some cases or don't want to mess with deriving standard types:

struct qstring_compare_i
{
    bool operator()(const QString & x, const QString y) const
    { return QString::compare(x, y, Qt::CaseInsensitive) < 0; }
};

static QSet<QString> substract_sets(const QSet<QString> & qs1, const QSet<QString> & qs2)
{
    std::set<QString> r;
    std::set_difference(qs1.begin(), qs1.end(), qs2.begin(), qs2.end(), std::inserter(r, r.end()), qstring_compare_i());

    QSet<QString> result;
    for(std::set<QString>::iterator i=r.begin();i!=r.end();++i) {
        result << *i;
    }
    return result;
}
like image 91
Stephen Chu Avatar answered Dec 24 '22 03:12

Stephen Chu


The quickest way would be to sub-class the QString like this and override the comparators, in the example below I've done the equality operator:

  class QStringInsensitive: public QString
  {
     bool operator==(const QString& other) const
     {
        return (0 == this->compare(other, Qt::CaseInsensitive));
     }
  };
  QSet< QStringInsensitive > set;
like image 39
JadziaMD Avatar answered Dec 24 '22 05:12

JadziaMD