Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Intersection of two QMap
QtWS25 Last Chance

Intersection of two QMap

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 3 Posters 3.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Defohin
    wrote on last edited by Defohin
    #1

    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.

    the_T 1 Reply Last reply
    0
    • D Defohin

      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.

      the_T Offline
      the_T Offline
      the_
      wrote on last edited by
      #2

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

      -- No support in PM --

      D 1 Reply Last reply
      0
      • the_T the_

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

        D Offline
        D Offline
        Defohin
        wrote on last edited by
        #3

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

        the_T 1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #4
          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

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          3
          • D Defohin

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

            the_T Offline
            the_T Offline
            the_
            wrote on last edited by the_
            #5

            @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 ;)

            -- No support in PM --

            D 1 Reply Last reply
            2
            • the_T the_

              @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 ;)

              D Offline
              D Offline
              Defohin
              wrote on last edited by Defohin
              #6

              @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

              VRoninV 1 Reply Last reply
              0
              • D Defohin

                @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

                VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by VRonin
                #7

                @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());
                }
                

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                D 1 Reply Last reply
                2
                • VRoninV VRonin

                  @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());
                  }
                  
                  D Offline
                  D Offline
                  Defohin
                  wrote on last edited by
                  #8

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

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved