Intersection of two QMap



  • I was wondering, how to intersect two QMap<int, QString> keeping the int, for example:

        QMap<int, QString> a = {
            { 0, "foo" },
            { 1, "bar" },
            { 2, "fez" },
            { 3, "fiz" },
            { 4, "foz" },
            { 5, "biz" }
        };
    
        QMap<int, QString> b = {
            { 0, "foo" },
            { 1, "bar" },
            { 2, "biz" }
        };
    

    I just realized something, the b can be a QStringList as the key is useless in this cause cause I want only the key from the a.

    would be:

        QMap<int, QString> c = {
            { 0, "foo" },
            { 1, "bar" },
            { 5, "biz" }
        };
    

    Notice the 5 as the key for the biz value taken from the a map.
    I tried to find a function in Qt to do that but it only has to QSet but I need the keys.



  • @Defohin
    Maybe you should have a look at QMap::values()



  • @the_ How that would help me? I have only the values, I want to intersect a with ``b, it's like searching onausingb` and keeping the key as well.



  • template <class K, class T>
    QMap<K,T> intersect(QMap<K,T> collection, const QList<T>& searchList){
    for(auto i=collection.begin();i!=collection.end();){
    if(searchList.contains(i.value())) ++i;
    else i=collection.erase(i);
    }
    return collection;
    }
    

    Then use:
    auto c=intersect(a,b.values()); //move constructor triggered so very cheap



  • @Defohin
    QMap::values() gets you all values that are stored in the map.
    So you could iterate through the one map and compare the actual value with the values of the other map and put it into the result map when it matches.

    QMap<int, QString> a = {
            { 0, "foo" },
            { 1, "bar" },
            { 2, "fez" },
            { 3, "fiz" },
            { 4, "foz" },
            { 5, "biz" }
        };
    
        QMap<int, QString> b = {
            { 0, "foo" },
            { 1, "bar" },
            { 2, "biz" }
        };
        QMap<int, QString> c;
        QList<QString> localValues = b.values();
        for(int x=0;x<a.size();x++) {
            if(localValues.contains(a.value(x)))
                c.insert(x,a.value(x));
        }
        qDebug() << c;
    

    will print

    QMap((0, "foo")(1, "bar")(5, "biz"))
    

    EDIT:
    @VRonin's template may be the prefered solution ;)



  • @the_ It's a really good answer.

    I did it that way:

        QMap<int, QString> a = {
            { 0, "foo" },
            { 1, "bar" },
            { 2, "fez" },
            { 3, "fiz" },
            { 4, "foz" },
            { 5, "biz" }
        };
    
        QStringList b = { "foo", "bar", "biz" };
    
        QMap<int, QString> inter;
    
        foreach (QString value, b) {
            if (! a.values().contains(value)) continue;
            inter.insert(a.key(value), value);
        }
    
        qDebug() << inter.keys() << inter.values();
    

    I changed the second QMap to QStringList cause the second QMap keys is kinda useless.

    If you want to improve the code I sent, feel free to do so



  • @Defohin said in Intersection of two QMap:

    If you want to improve the code I sent, feel free to do so

    use const references in foreach, see http://blog.qt.io/blog/2009/01/23/iterating-efficiently/

    If you expect the majority of the values of a not to be in b then use your solution, otherwise, if you expect the majority of a being included in b use my subtractive one

    if you do not care about the order of b use QSet as contains is much faster:

    QMap<int, QString> a = {
            { 0, "foo" },
            { 1, "bar" },
            { 2, "fez" },
            { 3, "fiz" },
            { 4, "foz" },
            { 5, "biz" }
        };
    
        QSet<QString> b = { "foo", "bar", "biz" };
    for(auto i=a.constBegin();i!=a.constEnd();++i){
    if(b.contains(i.value()))
    c.insert(i.key(),i.value());
    }
    


  • @VRonin Amazing, thank you, I'm going to improve my code using yours.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.