codebase
codebase

Reputation: 71

Could not print map of map value in C++

I have tried below code snippets to print map of map values but I could not able to access second map values.

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

int main()
{

map< string, std::map<std::string, int> > someStorage;
//First key values
someStorage["key1"]["This Is Layer one"] = 100;
someStorage["Key1"]["This Is Layer Two"] = 120;

//second key, values
someStorage["key2"]["This Is Layer one"] = 110;
someStorage["key2"]["This Is Layer Two"] = 110;
map< string, std::map<std::string, int> > ::iterator itr;
cout << "\nThe map is : \n";
for (itr = someStorage.begin(); itr != someStorage.end(); ++itr) 
{
 cout << '\t' << itr->first;
 //<< '\t' << (itr->second).first << '\n'  <==problematic part
 //<< '\t' << (itr->second).second << '\n';  <==problematic part
 }
 cout << endl;
return 0;
}

How to print/access these values and how do I differentiate "This Is Layer one" for "key1" and "key2". Because I can see that it is getting overwritten if we assign key2 value, key1 has same. Why?

Also I am expecting below key value pairs

Key1 => {This Is Layer one, 100} {This Is Layer Two, 120}

Key2 =>{This Is Layer one, 110} {This Is Layer Two, 110}

.

Upvotes: 1

Views: 1077

Answers (4)

codebase
codebase

Reputation: 71

Thank you for the output. My Gcc version did not support auto iterate

    for (itr1 = someStorage.begin(); itr1 != someStorage.end(); ++itr1)
{
    cout << '\t' << itr1->first << ":\n";
    std::map<std::string, int> ::iterator itr2;
    for (itr2 = itr1->second.begin(); itr2 != itr1->second.end(); ++itr2)
    {
         cout << "\t\t" << itr2->first << '\n';
         cout << "\t\t" << itr2->second << '\n';
    }
}

Upvotes: 0

Andreas DM
Andreas DM

Reputation: 11028

In addition to the other answers here, you can use structured binding (since c++17) to simplify this:

for (auto const& [key, val] : someStorage) { // val = second map
  for (auto const& [k, v] : val) {           // k = first, v = second
    cout << key << ' ' << k << ' ' << v << '\n';
  }
}

Upvotes: 4

Paul Evans
Paul Evans

Reputation: 27577

You'll need to iterate over your inner map as well, something like:

for (auto itr1 = someStorage.begin(); itr1 != someStorage.end(); ++itr1) 
{
    cout << '\t' << itr->first << ":\n";
    for (auto itr2 = itr1->second.begin(); itr2 != itr1->second.end(); ++itr2) 
    {
         cout << "\t\t" << itr2->first << '\n';
         cout << "\t\t" << itr2->second << '\n';
    }
}

Upvotes: 1

lubgr
lubgr

Reputation: 38325

You need a second, inner loop to traverse the nested std::map. Like this:

for (auto itr = someStorage.cbegin(); itr != someStorage.cend(); ++itr) 
{
    cout << itr->first << " => ";

    for (auto innerItr = itr->second.cbegin(); innerItr != itr->second.cend(); ++innerItr) 
    {
       cout << innerItr->first << " : " << innerItr->second << " ";
    }

    cout << "\n";
}

Note that for the desired output, you need to capitalize the keys such that they are "Key1" and "Key2" (this is currently a typo in your question). Note further that I changed to begin/end member functions to cbegin/cend, as the loop doesn't modify the container.

Upvotes: 2

Related Questions