Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > copy from keys from multimap into the vector

Reply
Thread Tools

copy from keys from multimap into the vector

 
 
puzzlecracker
Guest
Posts: n/a
 
      10-29-2008
I am using while loop for that but I am sure you can do it quicker and
more syntactically clear with copy function.

Here is what I do and would like to if someone has a cleaner solution:

vector<string> vec;
multimap<stirng, int> myMap

// populate myMap

multimap<string, int >::iterator iter = myMap.begin();

while(iter != myMap.end())
{
vec.push_back(iter->first)
}
 
Reply With Quote
 
 
 
 
peter koch
Guest
Posts: n/a
 
      10-29-2008
On 29 Okt., 20:33, puzzlecracker <(E-Mail Removed)> wrote:
> I am using while loop for that but I am sure you can do it quicker and
> more syntactically clear with copy function.
>
> Here is what I do and would like to if someone has a cleaner solution:
>
> * * vector<string> vec;
> * * multimap<stirng, int> myMap
>
> * *// populate myMap
>
> * * multimap<string, int >::iterator iter = myMap.begin();
>
> * * while(iter != myMap.end())
> * * {
> * * * * * *vec.push_back(iter->first)
> * * }


Whats wrong with
std::copy(myMap.begin(),myMap.end(),std::back_inse rter(vec)); ?

You could do a reserve on vec first to improve performance.

/Peter
 
Reply With Quote
 
 
 
 
AnonMail2005@gmail.com
Guest
Posts: n/a
 
      10-29-2008
> > I am using while loop for that but I am sure you can do it quicker and
> > more syntactically clear with copy function.

>
> > Here is what I do and would like to if someone has a cleaner solution:

>
> > * * vector<string> vec;
> > * * multimap<stirng, int> myMap

>
> > * *// populate myMap

>
> > * * multimap<string, int >::iterator iter = myMap.begin();

>
> > * * while(iter != myMap.end())
> > * * {
> > * * * * * *vec.push_back(iter->first)
> > * * }

>
> Whats wrong with
> std::copy(myMap.begin(),myMap.end(),std::back_inse rter(vec)); ?
>

A map's element contains both the key and the value so this is not
correct.
The OP just wants the key.
 
Reply With Quote
 
peter koch
Guest
Posts: n/a
 
      10-29-2008
On 29 Okt., 22:25, "(E-Mail Removed)" <(E-Mail Removed)>
wrote:
> > > I am using while loop for that but I am sure you can do it quicker and
> > > more syntactically clear with copy function.

>
> > > Here is what I do and would like to if someone has a cleaner solution:

>
> > > * * vector<string> vec;
> > > * * multimap<stirng, int> myMap

>
> > > * *// populate myMap

>
> > > * * multimap<string, int >::iterator iter = myMap.begin();

>
> > > * * while(iter != myMap.end())
> > > * * {
> > > * * * * * *vec.push_back(iter->first)
> > > * * }

>
> > Whats wrong with
> > std::copy(myMap.begin(),myMap.end(),std::back_inse rter(vec)); ?

>
> A map's element contains both the key and the value so this is not
> correct.
> The OP just wants the key.


I did not see that. Don't ask the question in the title (but read the
title anyway!).
In that case, I'd recommend having a look at Boosts iterator adaptors
which should do the job. But I admit that I haven't looked at that
part of Boost for a while (and never used it).

/Peter
 
Reply With Quote
 
AnonMail2005@gmail.com
Guest
Posts: n/a
 
      10-29-2008
> I am using while loop for that but I am sure you can do it quicker and
> more syntactically clear with copy function.
>
> Here is what I do and would like to if someone has a cleaner solution:
>
> * * vector<string> vec;
> * * multimap<stirng, int> myMap
>
> * *// populate myMap
>
> * * multimap<string, int >::iterator iter = myMap.begin();
>
> * * while(iter != myMap.end())
> * * {
> * * * * * *vec.push_back(iter->first)
> * * }


I think this works:

struct MyFunctor
{
typedef std::multimap <std::string, int> StringIntMultiMap;

std::string operator () (StringIntMultiMap::value_type const & v)
const
{
return v.first;
}
};

std::transform (myMap.begin (), myMap.end (), back_inserter (vec),
MyFunctor ());

HTH
 
Reply With Quote
 
Salt_Peter
Guest
Posts: n/a
 
      10-29-2008
On Oct 29, 2:33*pm, puzzlecracker <(E-Mail Removed)> wrote:
> I am using while loop for that but I am sure you can do it quicker and
> more syntactically clear with copy function.
>
> Here is what I do and would like to if someone has a cleaner solution:
>
> * * vector<string> vec;
> * * multimap<stirng, int> myMap
>
> * *// populate myMap
>
> * * multimap<string, int >::iterator iter = myMap.begin();
>
> * * while(iter != myMap.end())
> * * {
> * * * * * *vec.push_back(iter->first)
> * * }


You'll need a functor to extract that string from multimap's
value_type and std::transform can process the elements.

#include <iostream>
#include <ostream>
#include <string>
#include <vector>
#include <map>
#include <iterator>

template< typename P >
struct extract_first
{
const typename P::first_type&
operator()(const P& p) const
{
return p.first;
}
};

int main()
{
std::vector< std::string > vec;
std::multimap< std::string, int > mm;

// populate mm

typedef std::multimap< std::string, int >::value_type VType;

std::transform( mm.begin(),
mm.end(),
std::back_inserter(vec),
extract_first< VType >() );
}
 
Reply With Quote
 
puzzlecracker
Guest
Posts: n/a
 
      10-29-2008
On Oct 29, 5:25*pm, "(E-Mail Removed)" <(E-Mail Removed)>
wrote:
> > > I am using while loop for that but I am sure you can do it quicker and
> > > more syntactically clear with copy function.

>
> > > Here is what I do and would like to if someone has a cleaner solution:

>
> > > * * vector<string> vec;
> > > * * multimap<stirng, int> myMap

>
> > > * *// populate myMap

>
> > > * * multimap<string, int >::iterator iter = myMap.begin();

>
> > > * * while(iter != myMap.end())
> > > * * {
> > > * * * * * *vec.push_back(iter->first)
> > > * * }

>
> > Whats wrong with
> > std::copy(myMap.begin(),myMap.end(),std::back_inse rter(vec)); ?

>
> A map's element contains both the key and the value so this is not
> correct.
> The OP just wants the key.


Exactly... that's not going to work, I don't need the value_key, which
is pair<string, int>

Thanks
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      10-29-2008
Obnoxious User wrote:
> #include <vector>
> #include <map>
> #include <iterator>
> #include <algorithm>
> #include <iostream>
>
> template<typename C, typename M>
> class key_inserter :
> public std::iterator<std:utput_iterator_tag,void,void,v oid,void> {
> private:
> C & d_coll;
> public:
> key_inserter(C & c) : d_coll(c) {}
> key_inserter & operator*() { return *this; }
> key_inserter & operator++() { return *this; }
> key_inserter & operator++(int) { return *this; }
> key_inserter &
> operator=(typename M::value_type const & p) {
> d_coll.push_back(p.first);
> return *this;
> }
> };
>
> template<typename C, typename M>
> key_inserter<C,M> make_key_inserter(C & c, M & m) {
> return key_inserter<C,M>(c);
> }
>
> int main() {
> std::vector<int> v;
> std::map<int,int> m;
> m[0];m[1];m[2];m[6];
> std::copy(m.begin(),
> m.end(),
> make_key_inserter(v,m));
> std::copy(v.begin(),
> v.end(),
> std:stream_iterator<int>(std::cout,"\n"));
> return 0;
> }


Given that the while loop solution only requires 2 lines of code, I
think it's the easier solution...
 
Reply With Quote
 
Salt_Peter
Guest
Posts: n/a
 
      10-29-2008
On Oct 29, 2:33*pm, puzzlecracker <(E-Mail Removed)> wrote:
> I am using while loop for that but I am sure you can do it quicker and
> more syntactically clear with copy function.
>
> Here is what I do and would like to if someone has a cleaner solution:
>
> * * vector<string> vec;
> * * multimap<stirng, int> myMap
>
> * *// populate myMap
>
> * * multimap<string, int >::iterator iter = myMap.begin();
>
> * * while(iter != myMap.end())
> * * {
> * * * * * *vec.push_back(iter->first)
> * * }


You could use std::transform with std::back_inserter to load vector
and a functor to extract the std::string from multimap's value_type.

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <iterator>

template< typename P >
struct extract_first
{
const typename P::first_type&
operator()(const P& p) const
{
return p.first;
}
};

int main()
{
std::vector< std::string > vec;
std::multimap< std::string, int > mm;
// populate mm

typedef std::multimap< std::string, int >::value_type VType;

std::transform( mm.begin(),
mm.end(),
std::back_inserter(vec),
extract_first< VType >() );
}
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      10-30-2008
Salt_Peter wrote:

> On Oct 29, 2:33*pm, puzzlecracker <(E-Mail Removed)> wrote:
>> I am using while loop for that but I am sure you can do it quicker and
>> more syntactically clear with copy function.
>>
>> Here is what I do and would like to if someone has a cleaner solution:
>>
>> vector<string> vec;
>> multimap<stirng, int> myMap
>>
>> // populate myMap
>>
>> multimap<string, int >::iterator iter = myMap.begin();
>>
>> while(iter != myMap.end())
>> {
>> vec.push_back(iter->first)
>> }

>
> You could use std::transform with std::back_inserter to load vector
> and a functor to extract the std::string from multimap's value_type.
>
> #include <iostream>
> #include <string>
> #include <vector>
> #include <map>
> #include <algorithm>
> #include <iterator>
>
> template< typename P >
> struct extract_first
> {
> const typename P::first_type&
> operator()(const P& p) const
> {
> return p.first;
> }
> };
>
> int main()
> {
> std::vector< std::string > vec;
> std::multimap< std::string, int > mm;
> // populate mm
>
> typedef std::multimap< std::string, int >::value_type VType;
>
> std::transform( mm.begin(),
> mm.end(),
> std::back_inserter(vec),
> extract_first< VType >() );
> }


Alternatively, one can put the template inside:

// same headers

struct extract_first {

template< typename P >
typename P::first_type const &
operator()(const P& p) const {
return p.first;
}

};

int main() {
std::vector< std::string > vec;
std::multimap< std::string, int > mm;
// populate mm

std::transform( mm.begin(),
mm.end(),
std::back_inserter(vec),
extract_first() );
}

This makes extract_first oblivious to the type actually being used. I am not
sure, which is better. Any thoughts?


Best

Kai-Uwe Bux
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Ordering of same value keys in multimap Howard Hinnant C++ 1 08-28-2012 02:59 PM
stl multimap, insert with duplicate keys, is ordering stable? reppisch C++ 6 06-19-2007 09:38 AM
Initializing vector<vector<int> > and other vector questions... pmatos C++ 6 04-26-2007 05:39 PM
Free memory allocate by a STL vector, vector of vector, map of vector Allerdyce.John@gmail.com C++ 8 02-18-2006 12:48 AM
Distinct keys in the multimap Przemek C++ 3 01-31-2005 05:33 PM



Advertisments