Construct a std::map<T,U> from a std::vector<std::pair<T,U> >

218 Views Asked by At

How can I construct a std::map<std::string, Foo> from a std::vector<std::pair<std::string, Foo> >? It seems the std::map can be constructed from a input iterator.

UPDATE

Incidentally, I need to convert the strings in the vector to their lower case forms when adding them to the map. This is because I wish to use the map to get a sorted version of whats in the vector.

3

There are 3 best solutions below

0
On

Every standard library container can be constructed from an iterator range. In your case:

std::map<std::string, Foo> mymap(myvector.begin(), myvector.end());

If you want to add the lower-case versions of the strings, you need to pass the values through a transforming iterator. Unfortunately that’s not included in standard C++ but it’s rather straightforward to implement. Boost also includes a version:

// Make the pair's key lower-case
std::pair<std::string, Foo> make_lower(std::pair<std::string, Foo> x) {
    std::transform(x.first.begin(), x.first.end(), x.first.begin(), ::tolower);
    return x;
}

std::map<std::string, int> mymap(
    boost::make_transform_iterator(myvector.begin(), make_lower),
    boost::make_transform_iterator(myvector.end(), make_lower));

Here’s a complete, running demonstration

1
On
std::map<std::string, Foo> m;
std::vector<std::pair<std::string, Foo> > vec;

std::vector<std::pair<std::string, Foo> >::iterator it = vec.begin();

for(;it!=vec.end();++it)
{
  std::string temp = it->first;

  std::for_each(temp.begin(), temp.end(), 
        [](char& c){ tolower((unsigned char)c);}); 

  m[temp] = it->second;

 }
0
On

As per the map constructor definition,The function template argument InputIterator shall be an input iterator type that points to elements of a type from which value_type objects can be constructed (in map, value_type is an alias of pair< const key_type, mapped_type > )

std::vector<std::pair<std::string, Foo> > V;
//Fill the Vector V using make_pair...or other method
//Vector iterator can be used to construct the Map since you get the pair
std::map<std::string, Foo> M(V.begin(),V.end());