从 unordered_map 内的向量中删除元素

Posted

技术标签:

【中文标题】从 unordered_map 内的向量中删除元素【英文标题】:Deleting elements from vector inside unordered_map 【发布时间】:2021-03-14 09:17:00 【问题描述】:

在我的课堂上,我有一个无序的向量图,如下所示:

std::unordered_map<State, std::vector<std::shared_ptr<const City>>> citiesByState;

我的班级也有这两种方法:

  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-&gt;removeCity(State::NewYork, city),每次都看到向量不为空。我好像无法从 Vector 中删除。

我做错了什么?

【问题讨论】:

您尝试使用const std::shared_ptr&lt;const City&gt;&amp; 类型访问无序映射中的值,其中映射的键类型为State,在citiesByState.find(city) 行中。也许你想要的是citiesByState.find(state) @D-RAJ 这是一个错字。我正在按州找到它,但问题仍然存在。 【参考方案1】:

TL;DR

您正在从向量的副本中删除元素,而不是从存在于 std::unordered_map 中找到的 location 中的 std::vector 中。

长篇大论

当您在Manager::removeCity 中调用auto vector = location-&gt;second; 时,您将在if 语句的范围内复制该向量。因此,您的更改不会反映在您定位的容器中。只有您的副本会受到影响,并且在 if 语句的末尾也超出了范围,因此如果您找到 location 发生的所有事情都不会保存在 std::unordered_map 容器的状态中。

您可以通过直接调用location-&gt;second.clear() 来解决此问题,或者,如果您真的想给它另一个名称,请使用参考,例如auto&amp; vec = location-&gt;second; vec.clear();。请注意,这也适用于 Manager::addCity 方法。

附:为了避免混淆,我会避免使用与容器或 STL 中完善的类相同的变量名。

【讨论】:

这正是问题所在。如此琐碎却又如此容易错过。谢谢楼主!

以上是关于从 unordered_map 内的向量中删除元素的主要内容,如果未能解决你的问题,请参考以下文章

从循环内的向量中删除项目

如何在删除元素时防止重新散列 std::unordered_map?

从向量中删除一个元素而不删除之后的元素

从向量中删除元素时如何减小向量的大小?

从向量结构中删除元素[关闭]

分段错误:从二维向量中随机删除元素