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. QStringList erase()

QStringList erase()

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 3 Posters 1.9k Views 2 Watching
  • 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.
  • PerdrixP Offline
    PerdrixP Offline
    Perdrix
    wrote on last edited by
    #1

    I want to iterate over a QStringList and remove items that meet a specific criterion.

    Is it safe to use the following code:

    for (auto iter = list.begin(), iter!=list.end(), ++iter)
    {
        if (test for condition) 
        {
          iter = list.erase(iter); 
        }
    }
    

    Thanks
    D.

    J.HilkJ 1 Reply Last reply
    0
    • PerdrixP Perdrix

      I want to iterate over a QStringList and remove items that meet a specific criterion.

      Is it safe to use the following code:

      for (auto iter = list.begin(), iter!=list.end(), ++iter)
      {
          if (test for condition) 
          {
            iter = list.erase(iter); 
          }
      }
      

      Thanks
      D.

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      @Perdrix

      • safe ? yes
      • does it do what you think it does, I don't think so.

      I think, the way this loop is set up, double consecutive strings, that met your condition, only have 1 of the two removed

      Information provided without guarantee, as I haven't run any code:D


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      1
      • PerdrixP Offline
        PerdrixP Offline
        Perdrix
        wrote on last edited by Perdrix
        #3

        OK so you're telling me that's the WRONG way to do it (and I think I see what you're telling me).

        What's the correct way?

        Thanks
        David

        1 Reply Last reply
        0
        • Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by Chris Kawa
          #4

          Your loop would skip an element after erasure. Correct for loop would look like this:

          for (auto iter = list.begin(); iter!=list.end();)
          {
              if (/*test for condition*/) 
              {
                iter = list.erase(iter); 
              }
              else  
              {
                ++iter;
              }
          }
          

          but you can do the same a lot simpler:

          list.removeIf([](const QString& s) { return /* test s for condition */; });
          
          1 Reply Last reply
          4
          • PerdrixP Offline
            PerdrixP Offline
            Perdrix
            wrote on last edited by
            #5

            It look as if that nifty removeIf() mf is a Qt6 thing. So sadly I will have to use the other code...

            Thank you

            D.

            1 Reply Last reply
            0
            • Chris KawaC Offline
              Chris KawaC Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by Chris Kawa
              #6

              Well you can also use the old trusty remove_if/erase idiom:

              auto it = std::remove_if(list.begin(), list.end(), [](const QString& s) { return /*test s for condition*/; });
              list.erase(it, list.end());
              

              or a few characters shorter if you fancy some C++20 :)

              auto [beg, end] = std::ranges::remove_if(list, [](const QString& s) { return /*test s for condition*/; });
              list.erase(beg, end);
              
              1 Reply Last reply
              2
              • PerdrixP Offline
                PerdrixP Offline
                Perdrix
                wrote on last edited by
                #7

                @Chris-Kawa said in QStringList erase():

                auto it = std::remove_if(list.begin(), list.end(), [](const QString& s) { return /test s for condition/; });
                list.erase(it, list.end());

                Did you mean:

                auto it = std::remove_if(list.begin(), list.end(), [](const QString& s) { return /*test s for condition*/; });
                list.erase(it);
                

                As I think what you posted said erase from the current iterator to the end of list - but as I've not met that idiom b4 I could well be completely wrong ... What I want is to delete only the items that meet the predicate.

                Thanks
                David

                Chris KawaC 1 Reply Last reply
                0
                • PerdrixP Perdrix

                  @Chris-Kawa said in QStringList erase():

                  auto it = std::remove_if(list.begin(), list.end(), [](const QString& s) { return /test s for condition/; });
                  list.erase(it, list.end());

                  Did you mean:

                  auto it = std::remove_if(list.begin(), list.end(), [](const QString& s) { return /*test s for condition*/; });
                  list.erase(it);
                  

                  As I think what you posted said erase from the current iterator to the end of list - but as I've not met that idiom b4 I could well be completely wrong ... What I want is to delete only the items that meet the predicate.

                  Thanks
                  David

                  Chris KawaC Offline
                  Chris KawaC Offline
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on last edited by Chris Kawa
                  #8

                  @Perdrix No, I meant what I wrote.

                  std::remove_if is a bit of a misnomer. Unlike the removeIf() in Qt It doesn't remove anything, just rearranges elements so that the items that satisfy the predicate are moved to the back of the container. The returned iterator points to the first such item (or end() if none was found). To actually erase these elements a call to erase is made with a range [it, end).

                  The modification you made would just erase a single element, which is incorrect.

                  1 Reply Last reply
                  3
                  • PerdrixP Offline
                    PerdrixP Offline
                    Perdrix
                    wrote on last edited by
                    #9

                    OK thanks for the explanation

                    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