Copy Map Values to Vector in Stl

Copy map values to vector in STL

You can't easily use a range here because the iterator you get from a map refers to a std::pair, where the iterators you would use to insert into a vector refers to an object of the type stored in the vector, which is (if you are discarding the key) not a pair.

I really don't think it gets much cleaner than the obvious:

#include <map>
#include <vector>
#include <string>
using namespace std;

int main() {
typedef map <string, int> MapType;
MapType m;
vector <int> v;

// populate map somehow

for( MapType::iterator it = m.begin(); it != m.end(); ++it ) {
v.push_back( it->second );
}
}

which I would probably re-write as a template function if I was going to use it more than once. Something like:

template <typename M, typename V> 
void MapToVec( const M & m, V & v ) {
for( typename M::const_iterator it = m.begin(); it != m.end(); ++it ) {
v.push_back( it->second );
}
}

How to retrieve all keys (or values) from a std::map and put them into a vector?

While your solution should work, it can be difficult to read depending on the skill level of your fellow programmers. Additionally, it moves functionality away from the call site. Which can make maintenance a little more difficult.

I'm not sure if your goal is to get the keys into a vector or print them to cout so I'm doing both. You may try something like this:

std::map<int, int> m;
std::vector<int> key, value;
for(std::map<int,int>::iterator it = m.begin(); it != m.end(); ++it) {
key.push_back(it->first);
value.push_back(it->second);
std::cout << "Key: " << it->first << std::endl();
std::cout << "Value: " << it->second << std::endl();
}

Or even simpler, if you are using Boost:

map<int,int> m;
pair<int,int> me; // what a map<int, int> is made of
vector<int> v;
BOOST_FOREACH(me, m) {
v.push_back(me.first);
cout << me.first << "\n";
}

Personally, I like the BOOST_FOREACH version because there is less typing and it is very explicit about what it is doing.

C++ copy map to vector with std::move

Is it right to use std::move here?

If you are sure that you won't access the moved values in the future, yes.


You might also want to use std::vector::reserve to preallocate the required space in v.

v.reserve(v.size() + names.size());

C++ how to copy a map to a vector

This should do what you want:

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

using namespace std;

bool cmp(const pair<int, int> &p1, const pair<int, int> &p2)
{
return p1.second < p2.second;
}

int main()
{
map<int, int> m;
for(int i = 0; i < 10; ++i)
m[i] = i * -i;

vector<pair<int, int> > v;
copy(m.begin(), m.end(), back_inserter(v));

sort(v.begin(), v.end(), cmp);

for(int i = 0; i < v.size(); ++i)
cout << v[i].first << " : " << v[i].second << endl;
return 0;
}

How to copy vector to map in STL in a graceful way

Your code works (noting Michael J's suggestion to not process the last element if there is an odd number).

There is a small improvement that can be made. The call map[vec[x]] constructs an entry using the default constructor of the value_type, and then the copy-assignment operator copies the value from vec[x+1].

You could avoid the copy-assignment step by doing:

the_map.insert( std::make_pair(vec[x], vec[x+1]) );

I think this ends up having the map entry copy-constructed from the pair. In C++11 you can do:

the_map.emplace(vec[x], vec[x+1]);

which allows the compiler to minimize the amount of copying done. If your object supports move semantics and you want to destroy the vector afterwards, you can even go:

the_map.emplace( std::move(vec[x]), std::move(vec[x+1]) );

Is it possible to use STL copy function with map

You could use std::transform instead:

template <typename T, typename U>
const U &extract_second(const std::pair<T,U> &p)
{
return p.second;
}

std::transform(test.begin(), test.end(), test_arr, extract_second<int,double>);

And as @Andre points out in a comment below, if you want a slightly more verbose overhead, you can avoid having to explicitly state the template arguments via a functor:

struct extract_second
{
template <typename T, typename U>
const U operator() (const std::pair<T,U> &p) const
{
return p.second;
}
};

std::transform(test.begin(), test.end(), test_arr, extract_second());

I'm sure there's a less-verbose solution using Boost binders, but I can't remember the syntax off the top of my head.

Copy std::map data to another map

Copying one map to another can be done with operator = or the copy constructor.

E.g

map<X, Y> mp1; 
//fill mp1 with data
map<X, Y> mp2(mp1); //mp2 is a copy of mp1 (via copy-construction)
map<X, Y> mp3;
mp3 = mp2; // mp3 is also a copy of mp2 (via copy-assignment)


Related Topics



Leave a reply



Submit