Thread: deleting specific elements from map

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    630

    deleting specific elements from map

    Hello

    I have a map with int key and object element:

    Code:
    map<unsigned int, object> some_map;
    
    class object {
    public:
    	int get_somenum() { return somenum; }
    
    private:
    	int somenum;
    };
    I want to erase all object elements from some_map which have somenum (get_somenum()) smaller than number 10.

    What is the easiest way to do that in one line with those c++ algorithms like std::sort, boost::bind, ..?

    Many thanks in advance!

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Until someone comes out with a library of functions that support SQL on a map, (specifically, a DELETE with a WHERE clause), you'll have to iterate through the map and apply the condition and call the appropriate remove or delete method yourself.

    The easiest way would be to read a book that describes the STL map methods and implement the one that suits you. That way, next week, when you want the 2nd easiest way to do it, you'll already now the answer.
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Wow, looking at map/algorithm references I don't see anything in it that would let you do that on one line - boost or no boost, notably map doesn't have a remove_if method like std::list.

    You might write a generic function that takes a container and applies the erase method correctly on each item that meets a condition (but then it would also take a lot of work to make it for map::value_type - so it might be specifically meant for maps).
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I too was surprised not to find any sort of std::erase_if or std::erase_iterator
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It seems worse than that: the Dinkumware reference is wrong (map::erase actually returns void) and there doesn't seem to be a way to get a next valid iterator (map::erase can invalidate all iterators, perhaps because of rebalancing, and the iterator in the map is a very complicated thing? - can't find anything in the standard).

    All in all it looks that map isn't meant to support something like this in the first place (at least effectively). Perhaps another container might be more suitable...?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    I just went through this (the "iterator issue") on another forum. Perhaps the technique shown there for list.erase() will also with for map.erase().

    http://forums.macrumors.com/showthread.php?t=573857
    Mainframe assembler programmer by trade. C coder when I can.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I haven't tried remove_if on a map, so I don't know if it works (you would think it would, but who knows edit: apparently not). You can't std::sort a map, since that requires a random access iterator.
    Last edited by tabstop; 10-07-2008 at 10:10 AM.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by anon
    It seems worse than that: the Dinkumware reference is wrong (map::erase actually returns void) and there doesn't seem to be a way to get a next valid iterator (map::erase can invalidate all iterators, perhaps because of rebalancing, and the iterator in the map is a very complicated thing? - can't find anything in the standard).
    The 2003 edition of the C++ Standard says quite clearly that "the erase members shall invalidate only iterators and references to the erased elements". Consequently, we just need to increment the iterator, and then pass the previous iterator to erase(). For example:
    Code:
    map<unsigned int, object>::iterator iter = some_map.begin();
    while (iter != some_map.end())
    {
        if (iter->second.get_somenum() < 10)
        {
            some_map.erase(iter++);
        }
        else
        {
            ++iter;
        }
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by anon View Post
    notably map doesn't have a remove_if method like std::list.
    the idiom for associative containers is remove_copy_if and then swap if you remove by predicate, or just map::erase for removement by key/iterator

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How do maps keep elements ordered?
    By nucleon in forum C++ Programming
    Replies: 7
    Last Post: 11-08-2008, 03:39 PM
  2. using realloc for a dynamically growing array
    By broli86 in forum C Programming
    Replies: 10
    Last Post: 06-27-2008, 05:37 AM
  3. filling a static member map variable
    By elad in forum C++ Programming
    Replies: 2
    Last Post: 09-17-2004, 12:43 PM
  4. help with Map and Vector
    By geeoff99 in forum C++ Programming
    Replies: 1
    Last Post: 12-06-2002, 12:56 PM
  5. deleting specific numbers
    By newbie2C++ in forum C++ Programming
    Replies: 4
    Last Post: 12-03-2001, 10:59 AM