C++ how to copy a map to a vector

29,692

Solution 1

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;
}

Solution 2

vector<pair<K,V> > v(m.begin(), m.end());

or

vector<pair<K,V> > v(m.size());
copy(m.begin(), m.end(), v.begin());

copy() is in <algorithm>.

Solution 3

If you're using a std::map, it's already sorted by the key. Just create an iterator and iterate over the map from begin() to end() and you're done.

If you'd like to sort by something other than the map key, you can use the same iterator and push a copy of each element onto your vector as you iterate over the map.

Solution 4

Assuming you want to copy the key and the value:

std::map<Foo, Bar> m;


// Map gets populated 
// (...)


// Copying it to a new vector via the constructor
std::vector<std::pair<Foo, Bar>> v(m.begin(), m.end());


// Copying it to an existing vector, erasing the contents
v.assign(m.begin(), m.end());

// Copying it to the back of an existing vector
v.insert(v.end(), m.begin(), m.end());

Solution 5

If your purpose is just to sort by the type instead of the key, you might want to look at Boost::Bimap. It lets you access both parts of the map pair as keys. Presumably you could iterate over it in order of the second key just as easily as the first.

Share:
29,692
Jack BeNimble
Author by

Jack BeNimble

Updated on July 09, 2022

Comments

  • Jack BeNimble
    Jack BeNimble almost 2 years

    What's the best way in C++ to copy a pair from a map to vector? I'm doing this so I can subsequently sort the vector.

    • David Rodríguez - dribeas
      David Rodríguez - dribeas about 15 years
      Maps are sorted. You should specify whether you want to sort on another parameter or with a different key. Else the question is self-answered: don't.
    • Drew Dormann
      Drew Dormann over 5 years
      Closing as duplicate, as the (newer) duplicate is much higher quality, in the opinion of several.
  • Jack BeNimble
    Jack BeNimble about 15 years
    I want to copy both. Once that's done, I need to figure out how to sort the vector by the second value in the pair.
  • Dean Burge
    Dean Burge about 15 years
    That last one is incorrect. Maybe you mean v.insert(v.rbegin().base(), m.begin(), m.end()); ?
  • Andrew Shepherd
    Andrew Shepherd about 15 years
    whihelmtell - Why do you think it's incorrect? I just tried it - it works fine.
  • Prabhu R
    Prabhu R about 15 years
    This one seems to be more elegant and simple
  • Andrew Shepherd
    Andrew Shepherd about 15 years
    Come to think of it: v.rebegin().base() returns the same iterator as v.end()
  • Functastic
    Functastic about 15 years
    It should be OK if v.size() >= 1. The range is inserted from the element before the position iterator.
  • Ankit Roy
    Ankit Roy about 15 years
    +1, clear & simple solution. @Jack: you should really put the info in your comment into the main question as it's highly relevant -- e.g. it would have prevented everyone from mentioning that maps are already sorted by their first elements.
  • Andrew Shepherd
    Andrew Shepherd about 15 years
    It's OK even if the vector is empty. In this case v.insert(v.end(), m_begin(). m.end()) is identical to v.insert(v.begin(), m_begin(). m.end()), because v.begin() == v.end().
  • Dean Burge
    Dean Burge about 15 years
    I think I misread that last line. Ignore my comment above. :)
  • Admin
    Admin about 15 years
    Thank you for optimal syntax snippets (for example the v.assign line).
  • foraidt
    foraidt about 14 years
    May be even simpler: You can specify a comparator in a map's CTor.
  • Christopher Howlin
    Christopher Howlin over 13 years
    Yes, this is the best, especially the first one. Just a few explaining comments: If you have typedef std::map<K,V> MapType you can't declare the vector vector<MapType::value_type> as value_type is pair<const K, V> which has no operator= and can't be copied into the vector. Also, in the second example it is really important to pass the size of the vector first (either through the constructor or reserve) because copy will not allocate space in the vector as elements are added and there is a strong chance you will run over the end of the vector's initial allocation.
  • yasith
    yasith about 12 years
    copy(m.begin(), m.end(), v.begin()); gave me a Segmentation Fault. Just saying.
  • Deepak Mohanty
    Deepak Mohanty over 5 years
    @yasith You need to reserve the size of the vector or use back_inserter().
  • Virus_7
    Virus_7 almost 3 years
    @DeepakMohanty Actually you need to use vector::resize() or vector::reserve AND back_inserter().