MM1
MM1

Reputation: 944

Iterating over unordered_map of vectors

I know this is some basic stuff but I can't manage to iterate over an unordered_map of std::vectors and print the content of each vector. My unordered_map looks like this:

std::unordered_map<std::string, std::vector<int> > _dict;

And for now I can just print the first attribute of the map:

for (auto &it : _dict)
{
    std::cout << it.first <<std::endl;
}

But it gives me an error when trying to print the second attribute. Does anyone know how I can achieve that ? Thanks!

Upvotes: 4

Views: 3509

Answers (3)

dfrib
dfrib

Reputation: 73176

C++17: Structured binding declaration in a range-based for loop

As of C++17, you may use a structured binding declaration as the range declaration in a range-based for loop, along with std::copy and std::ostream_iterator to write the consecutive std::vector elements to std::cout:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <unordered_map>
#include <vector>

int main() {
    const std::unordered_map<std::string, std::vector<int> > dict =  {
        {"foo", {1, 2, 3}},
        {"bar", {1, 2, 3}}
    };
    
    for (const auto& [key, v] : dict) {
        std::cout << key << ": ";
        std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
        std::cout << "\n";
    } 
    // bar: 1 2 3 
    // foo: 1 2 3 
    
    return 0;
}

Upvotes: 1

anastaciu
anastaciu

Reputation: 23792

You must use an inner loop for the vector.

The string is only one element, it can be printed as is, the vector is a collection of elements so it stands to reason that you need a loop to print its contents:

std::unordered_map<std::string, std::vector<int>> _dict;

for (auto &it : _dict)
{
    for (auto &i : it.second) // it.second is the vector
    {
        std::cout << i;
    }
}

If you want to print a particular item in the vector you need to access the position of that item you want to print:

for (auto &it : _dict)
{
    std::cout << it.second.at(0) << std::endl; //print the first element of the vector
}

Upvotes: 2

Christopher Miller
Christopher Miller

Reputation: 3451

You could use a range-for loop to print the contents of the std::vector <int>:

for(auto it : _dict){
    std::cout << it.first << ": ";

    for(int item : it.second){
        std::cout << item << " ";
    }
    std::cout << std::endl;
}

Upvotes: 0

Related Questions