I have the following data structure stored in a class.
class MyClass {
private:
std::map<std::string, std::set<std::string>> myMap;
public:
void remove(std::string id); //trying to remove items from sets inside myMap
}
There is then a method to attempt to delete items from the sets. I tried the following 2 ways but neither worked. Approach 1, use for
range.
for (auto pair : myMap) {
auto set = pair.second;
if (set.count(id)) {
set.erase(id);
}
}
Approach 2, use iterator
.
auto it = myMap.begin();
while (it != myMap.end()) {
auto set = it->second;
if (set.count(id)) {
set.erase(id);
}
it++;
}
What's the right way of removing elements from the sets inside a map in C++? Note that my code used to work when I had myMap
defined as std::map<std::string, std::set<std::string>*>
(pointers).
Suppose we have a std::map
like this:
std::map<std::string, std::set<std::string>> myMap;
myMap["a"].insert("aaa");
myMap["a"].insert("abb");
myMap["a"].insert("acc");
myMap["b"].insert("aaa");
myMap["b"].insert("abb");
myMap["b"].insert("acc");
Then you can delete items from std::set
by doing the following:
for (auto& i : myMap) {
i.second.erase("aaa");
}
Why approach from the question is not working?
Because, by doing the following for(auto pair : myMap) {...}
and auto set = pair.second;
you are actually working on the copy of the data from myMap
. So, instead you need to use references to the actual data like for(auto& pair : myMap) {...}
and auto& set = pair.second;
.
Furthermore, std::set::erase
removes the data from the std::set
if it exists so there is no need to manually check for the existence of the id.