C++ Map Container

The Map Container is one of many C++ containers that are used to store data. Moreover, Map belongs to the sub-branch of Associative containers, which store data in a sorted order. This makes accessing and searching through the data faster, and the cost of inserting data taking longer.


Creating a Map Container

What makes the Map Container different from other Associative Containers is that it stores data in the form key-value pairs. The Key is sort of like the Identification feature for the value, used to access and retrieve values from the Map. Keys must be unique, while values may be non-unique.

If you’ve ever used Dictionaries in Python, Maps in C++ are pretty much the same thing.

All container types in C++ are class templates, which means they are very flexible with what kind of data type that can store. Furthermore, this means they all have the same declaration method, making it easy to learn, remember and work with several container types.

The below code shows us to create a Map in C++. Unlike the other container types which just store individual data pieces, Map has key value pairs which may have different types. Because of this we have to define the type for both of them during declaration, like we have in the code above. The “Key” is of type int, and “Value” is of type string.

#include <iostream>
#include <map>
using namespace std;

int main() {
    map<int, string> m1;
    return 1;
}

Make sure to include the <map> header file!


Working with Maps

The first thing we need to do is add Data into our maps. The most common way of doing this is with pair<>(). Within the crocodile brackets, goes the data types of the Key-Value pair, and in the round brackets goes the actual Key-Value data.

    m1.insert(pair<int, string> (1, "Apple"));
    m1.insert(pair<int, string> (2, "Banana"));
    m1.insert(pair<int, string> (3, "Orange"));

Of course, the data types of the pair must match that of the Map into which you are putting it.

Accessing Data

Next up is accessing data. For this we usually use an iterator, the declaration of which is shown below.

    map<int, string>::iterator it;

It’s basically a pointer to the map, which you use to retrieve or assign values.

In the code below, we setup a for loop to iterate over all the elements in the map. In the initialization part of the for loop, we using the begin() method which returns an iterator to the beginning of the map. The stopping condition is if the iterator reaches the end of the map. Incrementing the iterator will make it point to the next Key-Value pair in the Map.

    for (it = m1.begin(); it != m1.end(); it++) {
        cout << "Key: " << it->first << "  Value: " << it->second << endl;
    }

Once we have the For loop set-up correctly, we can use the first attribute to return the Key, and the second attribute to retrieve the Value.

The reason we are using -> is because the iterator is a pointer.


Complete code

The complete code for the above example, if you want to try running it.

#include <iostream>
#include <map>
using namespace std;


int main() {
    map<int, string> m1;

    m1.insert(pair<int, string> (1, "Apple"));
    m1.insert(pair<int, string> (2, "Banana"));
    m1.insert(pair<int, string> (3, "Orange"));

    map<int, string>::iterator it;

    for (it = m1.begin(); it != m1.end(); it++) {
        cout << "Key: " << it->first << "  Value: " << it->second << endl;
    }

    return 1;
}

Acessing Data (Alternate way)

There is an alternate way of both adding, modifying and retrieving values from the Map Container in C++. Instead of insert() and pair you can just use the sub-script operator.

The below example adds two records using this method, one for “Orange” and one for “Grape”.

    m1.insert(pair<int, string> (1, "Apple"));
    m1.insert(pair<int, string> (2, "Banana"));

    m1[3] = "Orange"
    m1[4] = "Grape";

    map<int, string>::iterator it;

    for (it = m1.begin(); it != m1.end(); it++) {
        cout << "Key: " << it->first << "  Value: " << it->second << endl;
    }
Key: 1  Value: Apple
Key: 2  Value: Banana
Key: 3  Value: Orange
Key: 4  Value: Grape

Now let’s try modifying the data. We first insert two pairs of data, and then we use the sub-script operator to modify them.

    m1.insert(pair<int, string> (1, "Apple"));
    m1.insert(pair<int, string> (2, "Banana"));

    m1[1] = "Orange";
    m1[2] = "Grape";

    map<int, string>::iterator it;

    for (it = m1.begin(); it != m1.end(); it++) {
        cout << "Key: " << it->first << "  Value: " << it->second << endl;
    }
Key: 1  Value: Orange
Key: 2  Value: Grape

You can also retrieve values using the same sub-script operator, and having them printed out on screen. Of course, you need to use the keys in order to access these values.

int main() {
    map<int, string> m1;

    m1[1] = "Orange";
    m1[2] = "Grape";

    cout << m1[1] << endl;
    cout << m1[2] << endl;

    return 1;
}

The output:

Orange
Grape

Multi-Maps

A Multi-Map is just like a map, with one difference. They Key’s do not have to be unique, and can be duplicates of each other. However, the Value’s of these duplicate Key’s must be unique. In short, either the Key must be unique, or the Value. You cannot have two identical Key-Value pairs in a Multi-Map.

    multimap<int, string> mm1;

Other than this and a slight difference in the declaration, everything else works the same as regular maps.


Other Methods

find(): This method is used to locate certain values from the map. All you have to do is pass the Key, and an iterator to that Key-Value Pair will be returned.

int main() {
    map<int, string> m1;

    m1[1] = "Orange";
    m1[2] = "Grape";
    m1[3] = "Banana";
    m1[4] = "Coconut";

    map<int, string>::iterator it;

    it = m1.find(3);

    if (it != m1.end()) {
        cout << "Match Found";
    }
    else {
        cout << "Not Found";
    }

    return 1;
}
Not Found

The reason why you need to pass a Key, and not a Value is because the Key is unique, while the Values can be duplicated. So it makes more sense to have the Key as the identifying feature.

If the match was not found, it instead returns an iterator the end of the map, which we can use to determine whether a match was found or not.


This marks the end of the C++ Map Container Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments