Copying from maps to lists or vectors

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • pallav

    Copying from maps to lists or vectors

    I have a map like this:

    typedef boost::shared_p tr<NodeNodePtr;
    typedef std::vector<Nod ePtrNodeVecPtr;
    typedef std::map<std::s tring, NodePtrNodeMap;
    typedef std::map<std:st ring, NodePtr>::itera tor NodeMapItr;

    NodeMap nmap;

    In my classes, I often find myself copying the second arguments of
    maps to lists/vectors like this.

    NodeVecPtr nodes;
    for (NodeMapItr itr = nmap.begin(); itr != nmap.end(); ++itr)
    nodes.push_back (itr->second);

    I may also have node be a list of NodePtrs as opposed to vectors. I'm
    wondering if there is some standard STL routines, I can use to try to
    reduce this kind of code being repeated. I now std::copy() exists but
    it takes iterators. But since I'm dealing with maps, I'm not sure how
    to pass the second value as an iterator. There is also
    std::transform( ) but that also works with iterators.

    I've been searching the web, and found stuff like boost::bind and
    boost::iterator _adaptors that might work but I'm trying to read up the
    documentation to figure out the syntax.

    If somebody can help me in showing how I could accomplish this using
    STL/boost features, this will be helpful. Thanks for you time.

  • Gianni Mariani

    #2
    Re: Copying from maps to lists or vectors

    pallav wrote:
    I have a map like this:
    >
    typedef boost::shared_p tr<NodeNodePtr;
    typedef std::vector<Nod ePtrNodeVecPtr;
    typedef std::map<std::s tring, NodePtrNodeMap;
    typedef std::map<std:st ring, NodePtr>::itera tor NodeMapItr;
    >
    NodeMap nmap;
    >
    In my classes, I often find myself copying the second arguments of
    maps to lists/vectors like this.
    >
    NodeVecPtr nodes;
    for (NodeMapItr itr = nmap.begin(); itr != nmap.end(); ++itr)
    nodes.push_back (itr->second);
    NodeVecPtr nodes( nmap.begin(), nmap.end() );

    or

    nodes.append( nmap.begin(), nmap.end() );

    I don't know if std::list has an append method, but it does have an
    insert method that works like append.
    >
    I may also have node be a list of NodePtrs as opposed to vectors. I'm
    wondering if there is some standard STL routines, I can use to try to
    reduce this kind of code being repeated. I now std::copy() exists but
    it takes iterators. But since I'm dealing with maps, I'm not sure how
    to pass the second value as an iterator. There is also
    std::transform( ) but that also works with iterators.
    >
    I've been searching the web, and found stuff like boost::bind and
    boost::iterator _adaptors that might work but I'm trying to read up the
    documentation to figure out the syntax.
    >
    If somebody can help me in showing how I could accomplish this using
    STL/boost features, this will be helpful. Thanks for you time.
    >

    Comment

    • mlimber

      #3
      Re: Copying from maps to lists or vectors

      On Apr 17, 4:58 pm, Gianni Mariani <gi3nos...@mari ani.wswrote:
      pallav wrote:
      I have a map like this:
      >
      typedef boost::shared_p tr<NodeNodePtr;
      typedef std::vector<Nod ePtrNodeVecPtr;
      typedef std::map<std::s tring, NodePtrNodeMap;
      typedef std::map<std:st ring, NodePtr>::itera tor NodeMapItr;
      >
      NodeMap nmap;
      >
      In my classes, I often find myself copying the second arguments of
      maps to lists/vectors like this.
      >
      NodeVecPtr nodes;
      for (NodeMapItr itr = nmap.begin(); itr != nmap.end(); ++itr)
      nodes.push_back (itr->second);
      >
      NodeVecPtr nodes( nmap.begin(), nmap.end() );
      >
      or
      >
      nodes.append( nmap.begin(), nmap.end() );
      >
      I don't know if std::list has an append method, but it does have an
      insert method that works like append.
      But the map and the vector have different value_types, so this won't
      work.

      Cheers! --M

      Comment

      • mlimber

        #4
        Re: Copying from maps to lists or vectors

        On Apr 17, 2:55 pm, pallav <pallavgu...@gm ail.comwrote:
        I have a map like this:
        >
        typedef boost::shared_p tr<NodeNodePtr;
        typedef std::vector<Nod ePtrNodeVecPtr;
        typedef std::map<std::s tring, NodePtrNodeMap;
        typedef std::map<std:st ring, NodePtr>::itera tor NodeMapItr;
        >
        NodeMap nmap;
        >
        In my classes, I often find myself copying the second arguments of
        maps to lists/vectors like this.
        >
        NodeVecPtr nodes;
        for (NodeMapItr itr = nmap.begin(); itr != nmap.end(); ++itr)
        nodes.push_back (itr->second);
        >
        I may also have node be a list of NodePtrs as opposed to vectors. I'm
        wondering if there is some standard STL routines, I can use to try to
        reduce this kind of code being repeated. I now std::copy() exists but
        it takes iterators. But since I'm dealing with maps, I'm not sure how
        to pass the second value as an iterator. There is also
        std::transform( ) but that also works with iterators.
        >
        I've been searching the web, and found stuff like boost::bind and
        boost::iterator _adaptors that might work but I'm trying to read up the
        documentation to figure out the syntax.
        >
        If somebody can help me in showing how I could accomplish this using
        STL/boost features, this will be helpful. Thanks for you time.
        I don't have time to work up a complete solution here, but here's a
        snippet from Karlsson's Boost book (pp. 260f):

        void print_string( const std::string& s ) {
        std::cout << s << '\n';
        }

        // ...

        std::map<int, std::stringmy_m ap;
        my_map[0] = "Boost";
        my_map[1] = "Bind";
        std::for_each(
        my_map.begin(),
        my_map.end(),
        boost::bind( &print_strin g, boost::bind(
        &std::map<int,s td::string>::va lue_type::secon d, _1)
        )
        );

        That should get you started.

        Cheers! --M

        Comment

        • Gianni Mariani

          #5
          Re: Copying from maps to lists or vectors

          mlimber wrote:
          On Apr 17, 4:58 pm, Gianni Mariani <gi3nos...@mari ani.wswrote:
          >pallav wrote:
          But the map and the vector have different value_types, so this won't
          work.
          Ya - missed that one.

          OK - how about an interator that derefs to the second element ?


          psuedo code :

          template <typename T>
          struct second_iterator
          {

          T m_iterator;

          second_iterator ( const T& i_iterator );

          typename T::second_type & operator*()
          {
          return m_iterator->second;
          }

          ....
          };

          template <typename T>
          second_iterator <Tmake_second_i terator( const T & i_iterator )
          {
          return second_iterator <T>( i_iterator );
          }

          .... and then you can write:

          NodeVecPtr nodes(
          make_second_ite rator( nmap.begin() ),
          make_second_ite rator( nmap.end() )
          );

          Comment

          • James Kanze

            #6
            Re: Copying from maps to lists or vectors

            On Apr 17, 8:55 pm, pallav <pallavgu...@gm ail.comwrote:
            I have a map like this:
            typedef boost::shared_p tr<NodeNodePtr;
            typedef std::vector<Nod ePtrNodeVecPtr;
            typedef std::map<std::s tring, NodePtrNodeMap;
            typedef std::map<std:st ring, NodePtr>::itera tor NodeMapItr;
            NodeMap nmap;
            In my classes, I often find myself copying the second arguments of
            maps to lists/vectors like this.
            NodeVecPtr nodes;
            for (NodeMapItr itr = nmap.begin(); itr != nmap.end(); ++itr)
            nodes.push_back (itr->second);
            I may also have node be a list of NodePtrs as opposed to vectors. I'm
            wondering if there is some standard STL routines, I can use to try to
            reduce this kind of code being repeated. I now std::copy() exists but
            it takes iterators. But since I'm dealing with maps, I'm not sure how
            to pass the second value as an iterator. There is also
            std::transform( ) but that also works with iterators.
            I've been searching the web, and found stuff like boost::bind and
            boost::iterator _adaptors that might work but I'm trying to read up the
            documentation to figure out the syntax.
            If somebody can help me in showing how I could accomplish this using
            STL/boost features, this will be helpful. Thanks for you time.
            Wouldn't something like the following work:

            template< typename Map >
            struct ValueFromMap
            : public std::unary_func tion< typename Map::value_type ,
            typename Map::mapped_typ e >
            {
            typename Map::mapped_typ e operator()(
            typename Map::value_type const&
            elem ) const
            {
            return elem.second ;
            }
            } ;

            typedef boost::transfor m_iterator< ValueFromMap< NodeMap >,
            NodeMap::const_ iterator >
            ValueIter ;

            (I tried it with a std::map< std::string, int >, and it seemed
            to work.)

            --
            James Kanze (GABI Software) email:james.kan ze@gmail.com
            Conseils en informatique orientée objet/
            Beratung in objektorientier ter Datenverarbeitu ng
            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

            Comment

            Working...