从 unordered_map 内的向量中删除元素
Deleting elements from vector inside unordered_map
在我的 class 中,我有一个无序的矢量映射,如下所示:
std::unordered_map<State, std::vector<std::shared_ptr<const City>>> citiesByState;
我的class也有这两个方法:
void addCity(State state, const std::shared_ptr<const City>& city);
void removeCity(State state, const std::shared_ptr<const City>& city);
我添加一个城市,像这样:
void Manager::addCity(State state, const std::shared_ptr<const City>& city) {
auto location = citiesByState.find(state); // Find the state in the map
if (location == citiesByState.end()) { // If the state isn't in the map
std::vector<std::shared_ptr<const City>> cities; // Create a vector
cities.push_back(city); // Add the city
citiesByState[state] = cities; // Add the state and city vector to my map
} else {
auto vector = location->second; // Get the city vector. If the city isn't there already, add it.
if (std::find(vector.begin(), vector.end(), city) == vector.end()) {
vector.push_back(city);
}
}
}
现在这是我删除城市的代码:
void Manager::removeCity(State state, const std::shared_ptr<const City>& city) {
auto location = citiesByState.find(state);
if (location != citiesByState.end()) {
auto vector = location->second;
if (vector.size() > 0) {
std::cout << "Vector isn't empty." << std::endl;
}
vector.clear(); // Just empty it out for now.
}
}
然后我运行这样:
City city = ... // get city
manager->addCity(State::NewYork, city);
manager->removeCity(State::NewYork, city);
我可以重复调用manager->removeCity(State::NewYork, city)
,每次我都看到向量不为空。看来我无法从 Vector 中删除。
我做错了什么?
TL;DR
您正在从矢量副本中删除元素,而不是从 std::unordered_map
的找到的 location
中存在的 std::vector
。
长话短说
当您在 Manager::removeCity
中调用 auto vector = location->second;
时,您是在 if
语句的范围内制作该向量的副本。因此,您的更改不会反映在您定位的容器中。只有您的副本会受到影响,并且在 if
语句结束时也超出了范围,因此如果您发现 location
所发生的一切都不会保存在 [= 的状态中12=]容器。
你可以通过直接调用 location->second.clear()
来解决这个问题,或者,如果你真的想给它另一个名字,使用引用,例如auto& vec = location->second; vec.clear();
。请注意,这也适用于 Manager::addCity
方法。
P.S。为了避免混淆,我会避免使用与容器或 STL 中公认的 类 相同的变量名。
在我的 class 中,我有一个无序的矢量映射,如下所示:
std::unordered_map<State, std::vector<std::shared_ptr<const City>>> citiesByState;
我的class也有这两个方法:
void addCity(State state, const std::shared_ptr<const City>& city);
void removeCity(State state, const std::shared_ptr<const City>& city);
我添加一个城市,像这样:
void Manager::addCity(State state, const std::shared_ptr<const City>& city) {
auto location = citiesByState.find(state); // Find the state in the map
if (location == citiesByState.end()) { // If the state isn't in the map
std::vector<std::shared_ptr<const City>> cities; // Create a vector
cities.push_back(city); // Add the city
citiesByState[state] = cities; // Add the state and city vector to my map
} else {
auto vector = location->second; // Get the city vector. If the city isn't there already, add it.
if (std::find(vector.begin(), vector.end(), city) == vector.end()) {
vector.push_back(city);
}
}
}
现在这是我删除城市的代码:
void Manager::removeCity(State state, const std::shared_ptr<const City>& city) {
auto location = citiesByState.find(state);
if (location != citiesByState.end()) {
auto vector = location->second;
if (vector.size() > 0) {
std::cout << "Vector isn't empty." << std::endl;
}
vector.clear(); // Just empty it out for now.
}
}
然后我运行这样:
City city = ... // get city
manager->addCity(State::NewYork, city);
manager->removeCity(State::NewYork, city);
我可以重复调用manager->removeCity(State::NewYork, city)
,每次我都看到向量不为空。看来我无法从 Vector 中删除。
我做错了什么?
TL;DR
您正在从矢量副本中删除元素,而不是从 std::unordered_map
的找到的 location
中存在的 std::vector
。
长话短说
当您在 Manager::removeCity
中调用 auto vector = location->second;
时,您是在 if
语句的范围内制作该向量的副本。因此,您的更改不会反映在您定位的容器中。只有您的副本会受到影响,并且在 if
语句结束时也超出了范围,因此如果您发现 location
所发生的一切都不会保存在 [= 的状态中12=]容器。
你可以通过直接调用 location->second.clear()
来解决这个问题,或者,如果你真的想给它另一个名字,使用引用,例如auto& vec = location->second; vec.clear();
。请注意,这也适用于 Manager::addCity
方法。
P.S。为了避免混淆,我会避免使用与容器或 STL 中公认的 类 相同的变量名。