Copying C++ Map into key and value vectors

16,071

Solution 1

Your first question, "how can I push the first column of my map into one vector and the 2nd column into another" is solved thus:

std::map<std::string, std::string> mymap;
std::vector<std::string> keys;
std::vector<std::string> values;
for ( std::map<std::string,std::string>::iterator it=mymap.begin() ; it != mymap.end(); ++it )
{
  keys.push_back(it->first);
  values.push_back(it->second);
}

Your second question, "how would insert all the integers i into (*it).first ?" is solved thus:

std::map<int, int> mymap2;
for(int i = 0; i < 10; i++)
{
  // Insert default value into map
  // This sets '(*it).first' to 'i' and
  // '(*it).second' to a default value (in
  // this case, 0).
  mymap2[i];
}

or

std::map<int, int> mymap3;
for(int i = 0; i < 10; i++)
{
  // Insert specified value into map
  // this sets '(*it).first' to 'i', and
  // '(*it).second' to the value returned from the function.
  maymap3[i] = ChooseSpecificValue(i);
}

Solution 2

Use std::transform.

First define two functions key and value which take the pair of strings and return the first or second value, respectively.

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

const std::string& key(const std::pair<std::string, std::string>& keyValue)
{
    return keyValue.first;
}

const std::string& value(const std::pair<std::string, std::string>& keyValue)
{
    return keyValue.second;
}

Then use std::transform from <algorithm> with the functions to transform the map into either a vector of keys or a vector of values.

int main()
{
    using namespace std; // be explicit normally, trying to be brief here

    map<string, string> contacts;

    contacts["alice"] = "555-2701";
    contacts["bob"] = "555-2702";

    vector<string> keys(contacts.size());
    vector<string> values(contacts.size());

    transform(contacts.begin(), contacts.end(), keys.begin(), key);
    transform(contacts.begin(), contacts.end(), values.begin(), value);

    cout << "Keys:\n";
    copy(keys.begin(), keys.end(), ostream_iterator<string>(cout, "\n"));

    cout << "\n";

    cout << "Values:\n";
    copy(values.begin(), values.end(), ostream_iterator<string>(cout, "\n"));

    return 0;
}

Output:

Keys:
alice
bob

Values:
555-2701
555-2702

Solution 3

Well, it can be done with a simple loop:

for (auto const& p: mymap) {
  vec1.push_back(p.first);
  vec2.push_back(p.second);
}

Or using the std::transform algorithm, though it's quite verbose here:

std::transform(mymap.begin(), mymap.end(), std::back_inserter(vec1),
               [](MyMap::const_reference p) { return p.first; });

Solution 4

Assuming you've declared your map as string key and value (ie map<string, string> mymap; then it would be like below, also assuming you've declare 'it' variable as map<string, string>::iterator it, etc:

std::vector<std::string> test;
std::vector<std::string> second;
std::map<string, string>::iterator it;

for ( it=mymap.begin() ; it != mymap.end(); it++ )
{
    test.push_back((*it).first);
    second.push_back((*it).second);
}

Not sure about your next question.

Share:
16,071
CodersSC
Author by

CodersSC

Staffordshire University, Computer Science

Updated on June 14, 2022

Comments

  • CodersSC
    CodersSC almost 2 years

    I have a map and I want the first column i.e (*it).first to be pushed back into a vector then (*it)->second to be pushed back into another vector

    Is this the best way to do it?

    std::vector<std::string>test;
    for ( it=mymap.begin() ; it != mymap.end(); it++ )
    {
        test.push_back((*it).first);
    }
    

    My other question is if i have a loop i.e how would I insert all the integers i into (*it).first?

    for(int i = 0; i < 10; i++)
    {
        // 1 - 10 will go in (*it).first
    }
    

    I want to have some integers in (*it).first and have associated values in (*it).second;