I have declared a set inside a map in c++ as std::map<std::string, std::set<std::string>>
. How to loop to access or print the set values ?
-
Maybe you should be using [`std::multimap`](http://en.cppreference.com/w/cpp/container/multimap) instead? – wilx Mar 29 '16 at 08:20
2 Answers
If you know how to iterate a std::map
or a std::set
individually, you should have no troubles iterating them in combination. Note that if you iterate a std::map
using a range-based for
loop, you're iterating std::pair<K, V>
s where K
is the (const
-qualified) type of the key and V
the type of the values. If you only want to iterate a single set (associated with a a single key), simply access that element and iterate it as normal.
#include <iostream>
#include <map>
#include <set>
#include <string>
int
main()
{
auto stuff = std::map<std::string, std::set<std::string>> {
{"fruits", {"apple", "banana", "orange"}},
{"vegetables", {"carrot", "cucumber"}},
{"nuts", {"peanut", "walnut", "hazelnut", "coconut"}},
};
// Iterate over a single set
for (const auto& s : stuff["fruits"])
std::cout << s << "\n";
std::cout << "\n";
// Iterate over the whole data structure
for (const auto& pair : stuff)
{
std::cout << pair.first << ":";
for (const auto& s : pair.second)
std::cout << " " << s;
std::cout << "\n";
}
}
Output:
apple
banana
orange
fruits: apple banana orange
nuts: coconut hazelnut peanut walnut
vegetables: carrot cucumber

- 24,280
- 5
- 45
- 92
Presumably that you have a std::map<std::string, std::set<std::string>>
, you can print the elements of the contained set
s with a double ranged for loop as the example below:
std::map<std::string, std::set<std::string>> mp {{"1", {"1", "2", "3"}},
{"2", {"4", "5", "6"}}};
for(auto &&p : mp) {
for(auto &&s : p.second) std::cout << s << " ";
std::cout << std::endl;
}
Or if you want something more fancy to impress your boss you could use a single ranged for loop with std::copy
and std::ostream_iterator
:
std::map<std::string, std::set<std::string>> mp {{"1", {"1", "2", "3"}},
{"2", {"4", "5", "6"}}};
for(auto &&p : mp) {
std::copy(std::begin(p.second), std::end(p.second),
std::ostream_iterator<std::string>(std::cout," "));
std::cout << std::endl;
}
edit:
The goal is we have a table with camera name and specs as {std::map> cameraSpec {{"camera1, {"Spec1", "Spec2", "Spec3"}}, {"camera2", {"Spec2", "Spec4", "Spec6"}}}; and I want to write a code to check which specification is highly desirable to the user ? Something similar to finding the frequency of a word from the given table. How to access the specs?
How to access individual elements of the map
Say you want to access an existent element in the map (i.e., you're sure the specific key exists). You could use the map
's subscript operator in the following way:
for(auto &&s : mp["camera2"]) {
// you loop over elements {"spec2", "spec4", "spec6"}
}
That is, mp["camera2"]
will return a reference to set in the map with values {"spec2", "spec4", "spec6"}
under the key "camera2".
If you're not sure that a key exists in the map, then use the member function map::find
. That is, first query the map if specific key you're looking for exists in it and then access the elements of the value/set in the same way as shown above:
auto it = mp.find("camera2");
if(it != mp.end()) {
for(auto &&s : it->second) {
// you loop over elements {"spec2", "spec4", "spec6"}
}
}
Notice that if key "camera2" exists in your map, then map::find
will return an iterator pointing to element associated with that particular key.
Now, the elements of the map are of type std::pair<const key_type, value_type>
(in our case std::pair<const std::string, std::set<std::string>>
).
If the key is not found std::map::find
is going to return an iterator pointing to one pass the end element of the map.
std::pair
has two members std::pair::first
and std::pair::second
. In our case std::pair::first
value is equal to the key's value (i.e,. "cammera2") and std::pair::second
is equal to the value under that key (i.e., the std::set
with values {"spec2", "spec4", "spec6"}
). That is why in the loop shown above we iterate over it->second
(i.e., the value/set under key "cammera2").

- 41,839
- 11
- 94
- 168
-
Is there a benefit to using r- value references here vs. const references? – Fred Larson Dec 05 '15 at 20:24
-
@FredLarson is good habbit to use `auto&&` in for ranged loop. In this particular case it makes no difference. – 101010 Dec 05 '15 at 20:25
-
-
@101010 Thank you so much. That was a good explanation. I appreciate it. – Tanya Dec 05 '15 at 22:59