Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. ATL / WTL / STL
  4. STL "for_each" algorithm.

STL "for_each" algorithm.

Scheduled Pinned Locked Moved ATL / WTL / STL
c++cssalgorithmsquestionannouncement
21 Posts 5 Posters 1 Views 1 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.
  • J Jorgen Sigvardsson

    Of course nothing happened with the old values in your map. Look at what you're doing! You're accepting a PAIR_KV by const reference. You then assign it to a stack based PAIR_KV object. You get a copy! You are modifying the local copy on the stack. Do this instead

    typedef map<string, string> MapStr;

    void FnObj::operator() (MapStr::value_type& PA) {
    if(PA.first == "Old Key") {
    PA.second = "This is the NEW value for the old key";
    }
    }

    Why did you have a const string as key to begin with? Look, I seriously believe that you should get a good book on STL. I recommend Generic Programming and the STL: Using and Extending the C++ Standard Template Library by Matthew H. Austern, ISBN 0201309564. -- You copy and paste yourself into my brain. You always find your way back into my brain.

    W Offline
    W Offline
    WREY
    wrote on last edited by
    #11

    You are great on the giving of advice, but very poor on the testing of your own advice, because if you had tested the advice you were giving, you would have discovered they DON'T WORK. I know they don't work because I applied what you suggested and ended up (the latest) with 6 errors!! Moreover, if you had looked closely, you would have seen that I had:

    typedef pair<string, string> PAIR_KV;

    That's my "value_type" for the map that you keep talking about so much. It's there! SEE! It's there! I don't need your "MapStr::value_type&" suggestion, but I used it anyway just to see if it would work, ... and IT DIDN'T!! So much for your well-informed advice. Yes, I had tried removing "const" from all the places they were being used and ended up with errors of one kind or another, and even tried using the reference straight from the parameter list of the function object "operator()" (without creating one on the stack). That didn't work either (meaning, it produced several errors)! If you had done the various testings as I did, you would have found that "for_each" is just not a good algorithm for dealing with maps. It's obvious you didn't know that, based on the incorrect advice you have been giving. NONE of the advice you have given so far worked. NONE! But there you are, telling me to go read up on certain STL books. FYI, I do my share of reading, and practicing with the STL almost every day. I certainly DON'T NEED another one of your gratuitous advice. KISS OFF!! William Fortes in fide et opere!

    J 1 Reply Last reply
    0
    • W WREY

      You are great on the giving of advice, but very poor on the testing of your own advice, because if you had tested the advice you were giving, you would have discovered they DON'T WORK. I know they don't work because I applied what you suggested and ended up (the latest) with 6 errors!! Moreover, if you had looked closely, you would have seen that I had:

      typedef pair<string, string> PAIR_KV;

      That's my "value_type" for the map that you keep talking about so much. It's there! SEE! It's there! I don't need your "MapStr::value_type&" suggestion, but I used it anyway just to see if it would work, ... and IT DIDN'T!! So much for your well-informed advice. Yes, I had tried removing "const" from all the places they were being used and ended up with errors of one kind or another, and even tried using the reference straight from the parameter list of the function object "operator()" (without creating one on the stack). That didn't work either (meaning, it produced several errors)! If you had done the various testings as I did, you would have found that "for_each" is just not a good algorithm for dealing with maps. It's obvious you didn't know that, based on the incorrect advice you have been giving. NONE of the advice you have given so far worked. NONE! But there you are, telling me to go read up on certain STL books. FYI, I do my share of reading, and practicing with the STL almost every day. I certainly DON'T NEED another one of your gratuitous advice. KISS OFF!! William Fortes in fide et opere!

      J Offline
      J Offline
      Jorgen Sigvardsson
      wrote on last edited by
      #12

      #include <map>
      #include <iostream>
      #include <utility>
      #include <algorithm>

      typedef std::map<int, int> IntMap;

      struct addone {
      void operator()(IntMap::value_type& v) const {
      v.second++;
      }
      };

      struct print {
      void operator()(IntMap::value_type& v) const {
      std::cout << "first = " << v.first << ", second = " << v.second << std::endl;
      }
      };

      int main(int argc, char* argv[])
      {
      IntMap map;

      map.insert(std::make\_pair(1, 1));
      map.insert(std::make\_pair(2, 2));
      map.insert(std::make\_pair(3, 3));
      map.insert(std::make\_pair(4, 4));
      map.insert(std::make\_pair(5, 5));
      
      std::for\_each(map.begin(), map.end(), print());
      std::for\_each(map.begin(), map.end(), addone());
      std::for\_each(map.begin(), map.end(), print());
      
      return 0;
      

      }

      I'm just being honest; Do yourself a favor - stop whining and pick up an STL book. -- You copy and paste yourself into my brain. You always find your way back into my brain.

      W 1 Reply Last reply
      0
      • J Jorgen Sigvardsson

        #include <map>
        #include <iostream>
        #include <utility>
        #include <algorithm>

        typedef std::map<int, int> IntMap;

        struct addone {
        void operator()(IntMap::value_type& v) const {
        v.second++;
        }
        };

        struct print {
        void operator()(IntMap::value_type& v) const {
        std::cout << "first = " << v.first << ", second = " << v.second << std::endl;
        }
        };

        int main(int argc, char* argv[])
        {
        IntMap map;

        map.insert(std::make\_pair(1, 1));
        map.insert(std::make\_pair(2, 2));
        map.insert(std::make\_pair(3, 3));
        map.insert(std::make\_pair(4, 4));
        map.insert(std::make\_pair(5, 5));
        
        std::for\_each(map.begin(), map.end(), print());
        std::for\_each(map.begin(), map.end(), addone());
        std::for\_each(map.begin(), map.end(), print());
        
        return 0;
        

        }

        I'm just being honest; Do yourself a favor - stop whining and pick up an STL book. -- You copy and paste yourself into my brain. You always find your way back into my brain.

        W Offline
        W Offline
        WREY
        wrote on last edited by
        #13

        KISS OFF!! Who needs your crappy little "int" addone sample? I've had enough of your unworkable samples in the past. I don't need anymore. If you didn't understand my last message, it states, "I do my share of reading just about everyday." I DON'T NEED you to tell me what to do. Take your crappy little "map.insert" sample and SHOVE IT!! It wouldn't hurt for you to do some reading of your own also. You clearly need it. All those unworkable advice you've been giving. You definitely need to do a lot of reading yourself. William Fortes in fide et opere!

        J J 2 Replies Last reply
        0
        • W WREY

          KISS OFF!! Who needs your crappy little "int" addone sample? I've had enough of your unworkable samples in the past. I don't need anymore. If you didn't understand my last message, it states, "I do my share of reading just about everyday." I DON'T NEED you to tell me what to do. Take your crappy little "map.insert" sample and SHOVE IT!! It wouldn't hurt for you to do some reading of your own also. You clearly need it. All those unworkable advice you've been giving. You definitely need to do a lot of reading yourself. William Fortes in fide et opere!

          J Offline
          J Offline
          Jorgen Sigvardsson
          wrote on last edited by
          #14

          At least you're entertaining. :) -- You copy and paste yourself into my brain. You always find your way back into my brain.

          W S 2 Replies Last reply
          0
          • J Jorgen Sigvardsson

            At least you're entertaining. :) -- You copy and paste yourself into my brain. You always find your way back into my brain.

            W Offline
            W Offline
            WREY
            wrote on last edited by
            #15

            Even that you lack. William Fortes in fide et opere!

            1 Reply Last reply
            0
            • W WREY

              KISS OFF!! Who needs your crappy little "int" addone sample? I've had enough of your unworkable samples in the past. I don't need anymore. If you didn't understand my last message, it states, "I do my share of reading just about everyday." I DON'T NEED you to tell me what to do. Take your crappy little "map.insert" sample and SHOVE IT!! It wouldn't hurt for you to do some reading of your own also. You clearly need it. All those unworkable advice you've been giving. You definitely need to do a lot of reading yourself. William Fortes in fide et opere!

              J Offline
              J Offline
              jbarton
              wrote on last edited by
              #16

              The code example provided by Jörgen Sigvardsson was correctly updating a map of ints. It is easy to change this example to work with strings. #include <map> #include <iostream> #include <utility> #include <algorithm> #include <string> typedef std::map<std::string,std::string> StringMap; struct update { void operator() ( StringMap::value_type& v ) const { if ( v.first == "second" ) v.second = "replaced value"; } }; struct print { void operator() ( StringMap::value_type& v ) const { std::cout << "first = " << v.first << ", second = " << v.second << std::endl; } }; int main( int argc, char* argv[] ) { StringMap testMap; testMap.insert( StringMap::value_type("first", "1") ); testMap.insert( StringMap::value_type("second", "2") ); testMap.insert( StringMap::value_type("third", "3") ); testMap.insert( StringMap::value_type("fourth", "4") ); testMap.insert( StringMap::value_type("fifth", "5") ); std::for_each(testMap.begin(), testMap.end(), print()); std::for_each(testMap.begin(), testMap.end(), update()); std::for_each(testMap.begin(), testMap.end(), print()); return 0; } However, as you know (from your comments in your original post), the code in the "update" functor is basically doing a find. However, since the for_each does a loop through all elements of the map, this is much less efficient than doing an actual find. If you need to do single updates to elements in a map which have particular key values, it would normally be better to just do the find and then update the element. The for_each algorithm is really only appropriate if you need to access every element in the container. Best regards, John

              W J 2 Replies Last reply
              0
              • J jbarton

                The code example provided by Jörgen Sigvardsson was correctly updating a map of ints. It is easy to change this example to work with strings. #include <map> #include <iostream> #include <utility> #include <algorithm> #include <string> typedef std::map<std::string,std::string> StringMap; struct update { void operator() ( StringMap::value_type& v ) const { if ( v.first == "second" ) v.second = "replaced value"; } }; struct print { void operator() ( StringMap::value_type& v ) const { std::cout << "first = " << v.first << ", second = " << v.second << std::endl; } }; int main( int argc, char* argv[] ) { StringMap testMap; testMap.insert( StringMap::value_type("first", "1") ); testMap.insert( StringMap::value_type("second", "2") ); testMap.insert( StringMap::value_type("third", "3") ); testMap.insert( StringMap::value_type("fourth", "4") ); testMap.insert( StringMap::value_type("fifth", "5") ); std::for_each(testMap.begin(), testMap.end(), print()); std::for_each(testMap.begin(), testMap.end(), update()); std::for_each(testMap.begin(), testMap.end(), print()); return 0; } However, as you know (from your comments in your original post), the code in the "update" functor is basically doing a find. However, since the for_each does a loop through all elements of the map, this is much less efficient than doing an actual find. If you need to do single updates to elements in a map which have particular key values, it would normally be better to just do the find and then update the element. The for_each algorithm is really only appropriate if you need to access every element in the container. Best regards, John

                W Offline
                W Offline
                WREY
                wrote on last edited by
                #17

                Thanks for replying. Your sample does work. :-D William Fortes in fide et opere!

                1 Reply Last reply
                0
                • J jbarton

                  The code example provided by Jörgen Sigvardsson was correctly updating a map of ints. It is easy to change this example to work with strings. #include <map> #include <iostream> #include <utility> #include <algorithm> #include <string> typedef std::map<std::string,std::string> StringMap; struct update { void operator() ( StringMap::value_type& v ) const { if ( v.first == "second" ) v.second = "replaced value"; } }; struct print { void operator() ( StringMap::value_type& v ) const { std::cout << "first = " << v.first << ", second = " << v.second << std::endl; } }; int main( int argc, char* argv[] ) { StringMap testMap; testMap.insert( StringMap::value_type("first", "1") ); testMap.insert( StringMap::value_type("second", "2") ); testMap.insert( StringMap::value_type("third", "3") ); testMap.insert( StringMap::value_type("fourth", "4") ); testMap.insert( StringMap::value_type("fifth", "5") ); std::for_each(testMap.begin(), testMap.end(), print()); std::for_each(testMap.begin(), testMap.end(), update()); std::for_each(testMap.begin(), testMap.end(), print()); return 0; } However, as you know (from your comments in your original post), the code in the "update" functor is basically doing a find. However, since the for_each does a loop through all elements of the map, this is much less efficient than doing an actual find. If you need to do single updates to elements in a map which have particular key values, it would normally be better to just do the find and then update the element. The for_each algorithm is really only appropriate if you need to access every element in the container. Best regards, John

                  J Offline
                  J Offline
                  Jorgen Sigvardsson
                  wrote on last edited by
                  #18

                  jbarton wrote: If you need to do single updates to elements in a map which have particular key values, it would normally be better to just do the find and then update the element. That depends a little on how many values you are updating. If you are updating few elements, then the approach you mention is more efficient. But if the number of values are many, then an iteration is faster. Assuming that the map is implemented as a balanced search tree, you need to find out how O(k * log(n)) relates to O(n), where k is the number of values to update, and n is the number of elements in the map. Of course, if it's a hashmap, then the approach you mention is most likely faster for basically all k (unless, of course, the hash algorithm is very slow). I guess it would be advantageous to encapsulate this algorithm into its own function, and let itself adapt to the problem size automatically. But hey, how would I know? I just post faulty samples and is a retard according to some. :) -- You're entertaining at least.

                  J 1 Reply Last reply
                  0
                  • J Jorgen Sigvardsson

                    jbarton wrote: If you need to do single updates to elements in a map which have particular key values, it would normally be better to just do the find and then update the element. That depends a little on how many values you are updating. If you are updating few elements, then the approach you mention is more efficient. But if the number of values are many, then an iteration is faster. Assuming that the map is implemented as a balanced search tree, you need to find out how O(k * log(n)) relates to O(n), where k is the number of values to update, and n is the number of elements in the map. Of course, if it's a hashmap, then the approach you mention is most likely faster for basically all k (unless, of course, the hash algorithm is very slow). I guess it would be advantageous to encapsulate this algorithm into its own function, and let itself adapt to the problem size automatically. But hey, how would I know? I just post faulty samples and is a retard according to some. :) -- You're entertaining at least.

                    J Offline
                    J Offline
                    jbarton
                    wrote on last edited by
                    #19

                    I think the idea of iterating through the map to update multiple elements has merit. If (for instance) I want to update the data associated with all keys that match a particular pattern, there really isn't any way that I could do it without iterating through all elements in the map. When I have a list of specific key values whose data I want to update, I find it difficult to set up a functor that efficiently checks for these key values and then updates the associated data values. It may be possible using another map or hash within the functor to lookup the key value and then get the replacement value. With only simple if / else if comparisons, I think that the overhead of the functor would probably remove any advantage gained by not using find on each key value. Unless the program I was writing was running too slowly and by profiling I found it to be due to using find to update the map, I would probably stick with using find. If you know of a better way of writing this functor, let me know. I am always interested in hearing other approaches. Best regards, John

                    1 Reply Last reply
                    0
                    • J Jorgen Sigvardsson

                      At least you're entertaining. :) -- You copy and paste yourself into my brain. You always find your way back into my brain.

                      S Offline
                      S Offline
                      Sebastian Benitez
                      wrote on last edited by
                      #20

                      Oh, please guys, continue fighting. This is very funny :laugh: "semper aliquid haeret", Bacon. -- Sebastián.

                      J 1 Reply Last reply
                      0
                      • S Sebastian Benitez

                        Oh, please guys, continue fighting. This is very funny :laugh: "semper aliquid haeret", Bacon. -- Sebastián.

                        J Offline
                        J Offline
                        Jorgen Sigvardsson
                        wrote on last edited by
                        #21

                        Hey, I'm not fighting. :) -- You're entertaining at least.

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups