如何删除存储在 std::map 中的 std::set 中的元素?
How do I delete elements from an std::set that is stored inside a std::map?
我将以下数据结构存储在 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
}
然后有一种方法可以尝试从集合中删除项目。我尝试了以下两种方法,但均无效。方法 1,使用 for
范围。
for (auto pair : myMap) {
auto set = pair.second;
if (set.count(id)) {
set.erase(id);
}
}
方法二,使用iterator
.
auto it = myMap.begin();
while (it != myMap.end()) {
auto set = it->second;
if (set.count(id)) {
set.erase(id);
}
it++;
}
在 C++ 中从映射中的集合中删除元素的正确方法是什么?请注意,当我将 myMap
定义为 std::map<std::string, std::set<std::string>*>
(指针)时,我的代码可以正常工作。
假设我们有这样一个std::map
:
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");
然后您可以通过执行以下操作从 std::set
中删除项目:
for (auto& i : myMap) {
i.second.erase("aaa");
}
为什么问题的方法不起作用?
因为,通过执行以下 for(auto pair : myMap) {...}
和 auto set = pair.second;
,您实际上是在处理来自 myMap
的数据副本。因此,您需要使用对实际数据的引用,例如 for(auto& pair : myMap) {...}
和 auto& set = pair.second;
.
此外,如果存在,std::set::erase
会从std::set
中删除数据,因此不需要手动检查 id 是否存在。
您正在复制要变异的对象。看来你有 Java 的背景。在 C++ 中,如果你想要引用语义(而不是值语义),你应该使用引用(auto &
而不是 auto
在这种情况下)。操作方法如下:
#include <algorithm>
#include <map>
#include <set>
#include <string>
class MyClass {
private:
std::map<std::string, std::set<std::string>> myMap;
public:
void remove(std::string const& id) {
std::for_each(myMap.begin(), myMap.end(),
[&id](auto& p) { p.second.erase(id); });
}
};
我将以下数据结构存储在 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
}
然后有一种方法可以尝试从集合中删除项目。我尝试了以下两种方法,但均无效。方法 1,使用 for
范围。
for (auto pair : myMap) {
auto set = pair.second;
if (set.count(id)) {
set.erase(id);
}
}
方法二,使用iterator
.
auto it = myMap.begin();
while (it != myMap.end()) {
auto set = it->second;
if (set.count(id)) {
set.erase(id);
}
it++;
}
在 C++ 中从映射中的集合中删除元素的正确方法是什么?请注意,当我将 myMap
定义为 std::map<std::string, std::set<std::string>*>
(指针)时,我的代码可以正常工作。
假设我们有这样一个std::map
:
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");
然后您可以通过执行以下操作从 std::set
中删除项目:
for (auto& i : myMap) {
i.second.erase("aaa");
}
为什么问题的方法不起作用?
因为,通过执行以下 for(auto pair : myMap) {...}
和 auto set = pair.second;
,您实际上是在处理来自 myMap
的数据副本。因此,您需要使用对实际数据的引用,例如 for(auto& pair : myMap) {...}
和 auto& set = pair.second;
.
此外,如果存在,std::set::erase
会从std::set
中删除数据,因此不需要手动检查 id 是否存在。
您正在复制要变异的对象。看来你有 Java 的背景。在 C++ 中,如果你想要引用语义(而不是值语义),你应该使用引用(auto &
而不是 auto
在这种情况下)。操作方法如下:
#include <algorithm>
#include <map>
#include <set>
#include <string>
class MyClass {
private:
std::map<std::string, std::set<std::string>> myMap;
public:
void remove(std::string const& id) {
std::for_each(myMap.begin(), myMap.end(),
[&id](auto& p) { p.second.erase(id); });
}
};